@linux1s1s
2019-02-14T01:53:51.000000Z
字数 2803
阅读 3859
AndroidExtend 2015-04
在Android中使用序列化,无非两种途经:
Parcelable和Serializable
public class SerializableDeveloper implements SerializableString name;int yearsOfExperience;List<Skill> skillSet;float favoriteFloat;static class Skill implements Serializable {String name;boolean programmingRelated;}}
serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。
class 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);}@Overridevoid 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];}};@Overrideint describeContents() {return 0;}}}
根据 google 工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。
因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。
通过将一个对象放到一个bundle里面然后调用Bundle#writeToParcel(Parcel, int)方法来模拟传递对象给一个activity的过程,然后再把这个对象取出来,在一个循环里面运行1000 次。

如果你想成为一个优秀的软件工程师,你需要多花点时间来实现 Parcelable ,因为这将会为你对象的序列化过程快10多倍,而且占用较少的资源。
但是大多数情况下, Serializable 的龟速不会太引人注目。你想偷点懒就用它吧,不过要记得serialization是一个比较耗资源的操作,尽量少使用。
如果你想要传递一个包含许多对象的列表,那么整个序列化的过程的时间开销可能会超过一秒,这会让屏幕转向的时候变得很卡顿
另外有一种说法是:在Activity之间传递数据使用Serializable在某种情况下会失败,这样的案例尚未遇到过。(个人猜测:难道是持久化数据需要写入扩展SD卡,如果一旦出现写入或者读取失败,那么传输就会失败)
本文翻译和整理自:http://www.developerphil.com/parcelable-vs-serializable/
