本文来自http://yanwushu.sinaapp.com/parcelable-vs-serializable/
在开发android程序过程中,我们都遇到过使用bundle在activity之间传递对象的问题。实现使用bundle传递对象,有两种选择,一种是将对象通过Serialize(序列化)的方式传递,一种是将对象通过parcel(打包)的方式传递。本文比较这两种方式的区别。
Serializable简单为主
public class SerializableDeveloperimplements Serializable Stringname; intyearsOfExperience; List<Skill>skillSet; floatfavoriteFloat; staticclass Skill implements Serializable { Stringname; booleanprogrammingRelated; } }
使用序列化方式实现对象传递的时候,只需要类及其内部类实现java.io.serialiable接口即可。 java.io.serializable 是一个没有任何待实现方法的标记接口。
序列化底层使用反射实现,效率较低,因为反射机制会生成大量的临时对象,并且直接对GC产生压力。
Parcelable高效是王
class ParcelableDeveloperimplements Parcelable { Stringname; intyearsOfExperience; List<Skill>skillSet; floatfavoriteFloat; ParcelableDeveloper(Parcelin) { this.name= in.readString(); this.yearsOfExperience= in.readInt(); this.skillSet= new ArrayList<Skill>(); in.readTypedList(skillSet,Skill.CREATOR); this.favoriteFloat= in.readFloat(); } voidwriteToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(yearsOfExperience); dest.writeTypedList(skillSet); dest.writeFloat(favoriteFloat); } intdescribeContents() { return0; } staticfinal Parcelable.Creator<ParcelableDeveloper> CREATOR =new Parcelable.Creator<ParcelableDeveloper>() ParcelableDevelopercreateFromParcel(Parcel in) { returnnew ParcelableDeveloper(in); } ParcelableDeveloper[]newArray(int size) { returnnew ParcelableDeveloper[size]; } }; staticclass Skill implements Parcelable { Stringname; booleanprogrammingRelated; Skill(Parcelin) { this.name= in.readString(); this.programmingRelated= (in.readInt() == 1); } @Override voidwriteToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(programmingRelated? 1 : 0); } staticfinal Parcelable.Creator<Skill> CREATOR =new Parcelable.Creator<Skill>() { SkillcreateFromParcel(Parcel in) { returnnew Skill(in); } Skill[]newArray(int size) { returnnew Skill[size]; } }; @Override intdescribeContents() { return0; } } }
根据google工程师的的观点,这种实现效率更高。原因之一是我们自己指定而非使用反射机制实现了保存和恢复的过程。并且在这个过程的自我实现中可以进行有效的优化。
然而,很显然,实现parcelable接口很费工夫,并且代码阅读性较低。
性能测试
下面比较两种实现方式具体的性能差异。
· 通过将对象放到bundle中并且取出,模仿activity传递对象的操作
· 重复这个过程1000次
· 执行十次取平均值
· 使用上文中的SerializableDeveloper和ParcelableDeveloper 进行测试
· 测试在下面三种设备上进行
o LG Nexus 4 – Android 4.2.2
o Samsung Nexus 10 – Android 4.2.2
o HTC Desire Z – Android 2.3.3
Nexus 10
Serializable: 1.0004ms, Parcelable: 0.0850ms
Nexus 4
Serializable: 1.8539ms –Parcelable: 0.1824ms
Desire Z
Serializable: 5.1224ms –Parcelable: 0.2938ms.
如你所见,parcelable方式要比序列化方式快十倍以上,并且,即使再小的对象,也要花费一毫秒以上的时间才能完成一个序列化和反序列化的过程。
选择
两种实现方式的区别在于实现过程的简易程度和执行速度,开发人员应该在这两者之间找到适合自己的平衡点。
资源