前几天我们说了Serializable,当然也少不了Parcleable
Parcelable同样也是一个接口,通过Parcelable我们同样可以实现对象的序列化,而且远比Serializable高效,不够其过程就要复杂点了。
我们简单的定义一个Person类,添加三个属性,然后实现Parcelable接口,AS会提示我们实现其方法,
我们只要点击 Add Parcelable Implementation,AS会自动帮我们实现其方法,如下
public class Person implements Parcelable {
private int id;
private String name;
private boolean sex;
private Class cls;
protected Person(Parcel in) {
id = in.readInt();
name = in.readString();
sex = in.readByte() != 0;
cls = in.readParcelable(Class.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeByte((byte) (sex ? 1 : 0));
dest.writeParcelable(cls, flags);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
Parcel
Parcel内部包装了可序列化的数据,可在Binder中传输,在上面代码中,我们可以看出,序列化过程需要实现序列化、反序列化和内容描述。
- writeToParcel完成序列化 ,通过Parcel的一系列write方法完成;
- CREATOR完成反序列化,内部标明了如何创建序列化对象和数组,通过Parcel的一系列read方法来完成反序列过程;
-
describeContents完成内容描述,几乎所有的情况下都返回0,仅当当前对象中存在文件描述符时,该方法返回1。
<u>在Persion(Parcel in)中,因为Class是另外一个可序列化的对象,所以它的反序列化过程需要传递当前线程的上下文加载器,否则会报无法找到类的错误。</u>
其实Android系统有很多实现了Parcelable接口的类,如Intent、Bundle、Bitmap等等,我们可以直接序列化它们,如果List和Map中的元素都是可序列化的,那List和Map也是可以序列化的。
关于Serializable和Parcelable的区别,我在另外一篇笔记中有提到Serializable和Parcelable的区别