持久化保存Parcelable实践
2016-05-03 00:17
471 查看
最近突发奇想,希望持久化保存Activity的信息,做应用恢复使用,而在Activity中最基本的Intent,Bundle都是基于Parcelable的,于是就研究了下Parcelable的持久化。
查阅了很多资料,无一例外的都有这样一段话(当然都是拿来主义)
Parcelable既然可以序列化,那么也就是Parcelable里面的数据按照一定的规则用字节流存起来了,既然如此,我们只要能够从Parcel中获取到字节流,其实也就完成了持久化Parcelable的工作了。
详细看了一下Parcel的代码,Android Studio确实方便,直接看反编译出来的文件(其实Android Studio已经对SDK的源码做了关联),Parcel中的unmarshall和marshall两个方法引起了我的注意,一个拿到字节数组,一个存入字节数组,完全就是我想要的嘛。
那么就做个demo试验一下,试验的思路如下:
准备一个实现Parcelable接口的类
准备DiskLruCache
写方法,把需要保存的数据通过Parcel序列化保存,拿到字节数组,存DiskLruCache
读方法,从DiskLruCache中读字节数组,然后放到Parcel里,在从Parcel中反序列化读出
编码
序列化的类
读方法和写方法
然后就是run了,数据顺利的保存,然后读取,只是在Parcel反序列化时有一点小挫折,原因就是,unmarshall之后要把Parcel的dataPosition重置,不然什么数据也读不到,这也是踩过坑才得出来的建议。
之后就完全与序列化时存入的数据一致了。
经过一番折腾,证明这思路是可行的。
如此看来,Parcelable持久化并不是不可行,只是适用场景的区别罢了。
通过这次尝试也加深的对Android序列化的理解,也是一次值得的实践。
查阅了很多资料,无一例外的都有这样一段话(当然都是拿来主义)
Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化
Parcelable既然可以序列化,那么也就是Parcelable里面的数据按照一定的规则用字节流存起来了,既然如此,我们只要能够从Parcel中获取到字节流,其实也就完成了持久化Parcelable的工作了。
详细看了一下Parcel的代码,Android Studio确实方便,直接看反编译出来的文件(其实Android Studio已经对SDK的源码做了关联),Parcel中的unmarshall和marshall两个方法引起了我的注意,一个拿到字节数组,一个存入字节数组,完全就是我想要的嘛。
那么就做个demo试验一下,试验的思路如下:
准备一个实现Parcelable接口的类
准备DiskLruCache
写方法,把需要保存的数据通过Parcel序列化保存,拿到字节数组,存DiskLruCache
读方法,从DiskLruCache中读字节数组,然后放到Parcel里,在从Parcel中反序列化读出
编码
序列化的类
private static class TestParcel implements Parcelable{ private String name; public TestParcel(String name) { this.name = name; } protected TestParcel(Parcel in) { this.name=in.readString(); } public static final Creator<TestParcel> CREATOR = new Creator<TestParcel>() { @Override public TestParcel createFromParcel(Parcel in) { return new TestParcel(in); } @Override public TestParcel[] newArray(int size) { return new TestParcel[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); } }
读方法和写方法
@TargetApi(Build.VERSION_CODES.FROYO) protected void load(){ File file = getExternalCacheDir(); if(!file.exists()){ file.mkdirs(); } try { cache=DiskLruCache.open(file,0,1,10*1024*1024); DiskLruCache.Snapshot snapshot= null; snapshot = cache.get("123456"); InputStream inputStream = snapshot.getInputStream(0); byte[] bytes = new byte[inputStream.available()]; inputStream.read(bytes); Parcel parcel = Parcel.obtain(); parcel.unmarshall(bytes,0,bytes.length); parcel.setDataPosition(0); int size = parcel.readInt(); List<TestParcel> list = new ArrayList<>(size); parcel.readTypedList(list,TestParcel.CREATOR); inputStream.close(); snapshot.close(); //cache.close(); } catch (IOException e) { e.printStackTrace(); } } @TargetApi(Build.VERSION_CODES.FROYO) protected void save(){ File file = getExternalCacheDir(); if(!file.exists()){ file.mkdirs(); } try { cache=DiskLruCache.open(file,0,1,10*1024*1024); DiskLruCache.Editor editor = cache.edit("123456"); OutputStream outputStream = editor.newOutputStream(0); BufferedOutputStream bos = new BufferedOutputStream(outputStream); Parcel parcel = Parcel.obtain(); List<TestParcel> list = new ArrayList<>(); for(int i = 0;i<10;i++){ list.add(new TestParcel("hello"+i)); } parcel.writeInt(list.size()); parcel.writeTypedList(list); bos.write(parcel.marshall()); bos.flush(); bos.close(); outputStream.flush(); outputStream.close(); editor.commit(); cache.flush(); } catch (IOException e) { e.printStackTrace(); } }
然后就是run了,数据顺利的保存,然后读取,只是在Parcel反序列化时有一点小挫折,原因就是,unmarshall之后要把Parcel的dataPosition重置,不然什么数据也读不到,这也是踩过坑才得出来的建议。
之后就完全与序列化时存入的数据一致了。
经过一番折腾,证明这思路是可行的。
如此看来,Parcelable持久化并不是不可行,只是适用场景的区别罢了。
通过这次尝试也加深的对Android序列化的理解,也是一次值得的实践。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories