背景:
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,感兴趣的可以自行查看源码。
文件名:一定要组织好,否则存在失败问题。上述方法已测试,可以执行