背景:
Android在序列化中,官方给出了Parcelable的方案,关于Parcelable的使用,可以参考Parcelable序列化教程
有了序列化的详细使用,我们肯定想知道如何把Parcelable序列化保存起来呢?常见的保存就是网络存储或者本地存储。
知道了本地存储,网络就是将byte字节传给服务器。接下来我们将会介绍设备本机上的序列化和反序列化
1.序列化
public static void save(Context context, Parcelable parcelable, String fileName) {
File file = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + fileName);
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream out = (new FileOutputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(out);
Parcel parcel = Parcel.obtain();
parcel.writeParcelable(parcelable, 0);
bos.write(parcel.marshall());
bos.flush();
bos.close();
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
在序列化过程中,保存的位置和文件的读写。如果是安全比较高的,建议保存在cache文件夹下,这样避免被清除了。文件名最好用英文,上面的方法就是采用cache文件夹。
文件的读写不在过多介绍
如何将Parcelable的对象变成二进制?离不开我们的老朋友Parcel,Parcel在Parcelable的序列化中也出现了,读写变量。
这里面同样,通过 Parcel parcel = Parcel.obtain();创建一个临时对象,
/**
* Retrieve a new Parcel object from the pool.
*/
public static Parcel obtain() {
final Parcel[] pool = sOwnedPool;
synchronized (pool) {
Parcel p;
for (int i=0; i<POOL_SIZE; i++) {
p = pool[i];
if (p != null) {
pool[i] = null;
if (DEBUG_RECYCLE) {
p.mStack = new RuntimeException();
}
return p;
}
}
}
return new Parcel(0);
}
接下来我们将Parcelable的对象保存到parcel中
parcel.writeParcelable(parcelable, 0);
通过parcel.marshall()将对象变成byte字节。
public final byte[] marshall() { return nativeMarshall(mNativePtr); }
这样我们将byte[]写到我们创建的文件中,至此,序列化已保存到我们的本地设备中
2.反序列化
了解了序列化过程,反序列化也是这些东西参与进来。
public static Parcelable getBeanByFileName(Context context, String fileName) {
File file = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + fileName);
People person=null;
try {
FileInputStream in = new FileInputStream(file);
byte[] bytes = new byte[in.available()];
in.read(bytes);
Parcel parcel = Parcel.obtain();
parcel.unmarshall(bytes, 0, bytes.length);
parcel.setDataPosition(0);
person = parcel.readParcelable(Thread.currentThread().getContextClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
return person;
}
2.1找到序列化的文件位置
2.2把文件的中信息读取存入字节数组。
2.3 创建一个临时的 Parcel parcel = Parcel.obtain();对象
2.4 通过parcel进行反序列化 parcel.unmarshall(bytes, 0, bytes.length);
2.5 将parcel反序列化对象读取出来
person = parcel.readParcelable(Thread.currentThread().getContextClassLoader());
这样反序列化结束。
关于parcel unmarshall和marshall,感兴趣的可以自行查看源码。
文件名:一定要组织好,否则存在失败问题。上述方法已测试,可以执行