Parcelable和Serializable有什么用,它们有什么差别?
Parcelable和Serializable都可以实现序列化,使对象可以变为二进制流在内存中传输数据。在Android中,只要实现二者之一就可以使用Intent和Binder来传递数据。实现了Parcelable接囗的类依赖于Parcel这个类来实现数据传递,它并不是一个一般化用途的序列化机制,主要用于IPC机制下的高性能传输。
差别
- 来源上
Parcelable是Android提供的序列化接口,Serializable是Java提供的序列化接口。因此Parcelable只能在Android中使用,而Serializable可以在任何使用Java语言的地方使用。
- 使用上
Parcelable使用起来比较麻烦,序列化过程需要实现Parcelable的writeToParcel(Parcel dest, int f1ags)
方法和describeContents()
方法。其中describeContents()
方法直接返回0就可以了。为了反序列化,还需要提供一个非空的名为CREATOR
的静态字段,该字段类型是实现了Parcelable.Creator接口的类,一般用一个匿名内部类实现就可以了。现在也有一些插件可以方便地实现Parcelable接口。
Serializable的使用就比较简单,直接实现Serializable接口即可,该接口没有任何方法。序列化机制依赖于一个long型的serialVersionUID
,如果没有显式的指定,在序列化运行时会基于该类的结构自动计算出一个值。如果类的结构发生变化就会导致自动计算出的serialVersionUID
不同。这就会导致一个问题,序列化之后类如果新增了一个字段,反序列过程就会失败。一般会报InvalidClassException这样的异常。
而如果显式的指定了serialversionUID
,只要类的结构不发生重大变化,如字段类型发生变化等,仅仅添加或者删除字段等都可以反序列化成功。
注意:如果要把对象持久化到存储设备或者通过网络传输到其它设备,最好使用Serializable。
- 效率上
Serializable的序列化和反序列化都需要使用到IO操作;而Parcelable不需要IO操作,Parcelable的效率要高于Serializable,Android中推荐使用Parcelable。
自定义一个类让其实现Parcelable,大致流程是什么?
自定义一个类让其实现Parcelable接口,大致流程是先实现该接口的writeToParcel(Parcel dest, int flags)
和describeContents()
方法。然后添加一个Parcelable.Creator类型的名字为CREATOR
的非空字段。例如:
public class Person implements Parcelable {
private String name;
private int age;
//...
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name); // 写出name
dest.writeInt(age); // 写出age
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.
Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
Person person = new Person();
person.name = source.readString(); // 读取name
person.age = source.readInt(); // 读取age
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
该类中的字段类型除了基本类型和String及它们对应的数组,如果有其它自定义的类型,也需要实现Parcelable或者Serializable接口。