Android中的Serializable和Parcelable
来源:互联网 发布:excel数据库设计 编辑:程序博客网 时间:2024/06/11 02:30
序列化原因
Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现序列化接口。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。从设计上我们就可以看出优劣了。
- 永久性保存对象,保存对象的字节序列到本地文件中;
- 通过序列化对象在网络中传递对象;
- 通过序列化在进程间传递对象。
至于选取哪种可参考下面的原则
1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。
两种方式实现
一:Serializable,要传递的类实现Serializable接口传递对象;
二:Parcelable,要传递的类实现Parcelable接口传递对象。
Serializable, 简单易用(Java自带):
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。
Serializable序列化不保存静态变量,可以使用Transient关键字对部分字段不进行序列化,也可以覆盖writeObject、readObject方法以实现序列化过程自定义。
// access modifiers, accessors and constructors omitted for brevitypublic class SerializableDeveloper implements Serializable String name; int yearsOfExperience; List<Skill> skillSet; float favoriteFloat; static class Skill implements Serializable { String name; boolean programmingRelated; }}
下来一个示例展示
// MainActivity中传递Intent open = new Intent(MainActivity.this,SecondActivity.class);Person person = new Person();// Person类是实现了Serializable接口的person.setName("张张");person.setAge(18);Bundle bundle = new Bundle();bundle.putSerializable("bundle_ser",person);open.putExtras(bundle);startActivity(open);// SecondActivity中接收Intent intent = getIntent();// 关键方法:getSerializableExtra ,我们的类是实现了Serializable接口的,所以写这个方法获得对象Person per = (Person)intent.getSerializableExtra("bundle_ser");
Parcelable, 速度至上(Android 专用):
除了Serializable之外,使用Parcelable也可以实现相同的效果,不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
根据 google 工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。
因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。
我们写一个实体类,实现Parcelable接口,马上就被要求
- 复写describeContents方法和writeToParcel方法
- 实例化静态内部对象CREATOR,实现接口Parcelable.Creator 。
也就是,随便一个类实现了Parcelable接口就一开始就会变成这样子,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
// access modifiers, accessors and regular constructors ommited for brevityclass ParcelableDeveloper implements Parcelable { String name; int yearsOfExperience; List<Skill> skillSet; float favoriteFloat; ParcelableDeveloper(Parcel in) { this.name = in.readString(); this.yearsOfExperience = in.readInt(); this.skillSet = new ArrayList<Skill>(); in.readTypedList(skillSet, Skill.CREATOR); this.favoriteFloat = in.readFloat(); } void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(yearsOfExperience); dest.writeTypedList(skillSet); dest.writeFloat(favoriteFloat); } int describeContents() { return 0; } static final Parcelable.Creator<ParcelableDeveloper> CREATOR = new Parcelable.Creator<ParcelableDeveloper>() { ParcelableDeveloper createFromParcel(Parcel in) { return new ParcelableDeveloper(in); } ParcelableDeveloper[] newArray(int size) { return new ParcelableDeveloper[size]; } }; static class Skill implements Parcelable { String name; boolean programmingRelated; Skill(Parcel in) { this.name = in.readString(); this.programmingRelated = (in.readInt() == 1); } @Override void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(programmingRelated ? 1 : 0); } static final Parcelable.Creator<Skill> CREATOR = new Parcelable.Creator<Skill>() { Skill createFromParcel(Parcel in) { return new Skill(in); } Skill[] newArray(int size) { return new Skill[size]; } }; @Override int describeContents() { return 0; } }}
示例演示
// MainActivity发送传递Intent mOpenThird = new Intent(MainActivity.this, ThirdActivity.class);Pen tranPen = new Pen();// Pen类是实现了Parcelable接口的tranPen.setColor("big red");tranPen.setSize(98);mOpenThird.putExtra("parcel_obj",tranPen);startActivity(mTvOpenThird);// ThirdActivity中接收Pen pen = (Pen)getIntent().getParcelableExtra("parcel_obj");
总结
如果你想成为一个优秀的软件工程师,你需要多花点时间来实现 Parcelable ,因为这将会为你对象的序列化过程快10多倍,而且占用较少的资源。
但是大多数情况下, Serializable 的龟速不会太引人注目。你想偷点懒就用它吧,不过要记得serialization是一个比较耗资源的操作,尽量少使用。
如果你想要传递一个包含许多对象的列表,那么整个序列化的过程的时间开销可能会超过一秒,这会让屏幕转向的时候变得很卡顿。
- Android中的Serializable和Parcelable
- Android中的Serializable和Parcelable
- Android中的Serializable和Parcelable序列化
- Android中的Serializable和Parcelable的qubie
- Android中的序列化Serializable和Parcelable
- android: Serializable 和 Parcelable
- 【Android】Serializable和Parcelable
- Android中的Parcelable接口和Serializable用法和区别
- [android] Serializable 和 Parcelable 区别
- android---- Serializable 和 Parcelable 区别
- android---- Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- [android] Serializable 和 Parcelable 区别
- 第八周 项目 1 - 建立顺序串的算法库
- hello world csdn
- Vijos P1889 天真的因数分解
- 关于 Java synchronized(this) 的问题?
- 处理started service的多次启动请求
- Android中的Serializable和Parcelable
- web服务器与应用服务器静态文件处理
- iOS开发之使用颜色生成图片
- winrar中文去广告版下载
- linux下find命令-atime,-ctime,-mtime真正含义
- Centos 7 安装 Python3.5.2后yum不能正常使用的解决办法
- Python:SQL
- 自动创建文件目录
- Java8 新特性之二---------接口的默认方法和静态方法