Contents
Android Parcel Parcelable
Parcel
Parcel是一个集装箱,Android通过IBinder来传送这个集装箱。集装箱里既允许放扁平化的数据,也可以存放active object IBinder引用。如果发送的是扁平化的数据,则在IPC的另一端对数据进行组装,如果发送的是IBinder引用,则IPC收到IBinder的代理,这一代理直接连到原始IBinder。
Parcel并非通用的序列化工具。这个类(和相应的可以放任意对象的Parcelable API)是为高效IPC而生。因此,Parcel中的数据不适宜永久存储,因为Parcel中任何一个数据的改变都将导致之前存储的数据变得没有意义。
Parcel提供了众多API解决各种数据类型的读写,这些API基本可归为六个主要类。
基本数据类型
writeInt(int), readInt()
基本数据类型阵列
writeIntArray(int[]), readIntArray(int[]), createIntArray()
Parcelables
Parcelable提供了一个从Parcel里高效(but low level)读写对象的方法。writeParcelable(Parcelable,int), readParcelable(ClassLoader), writeParcelableArray(T[], int), readParcelableArray(ClassLoader)这些方法将类和数据同时写入Parcel,读的时候通过类加载器恢复数据。
另一种更高效的方法:writeTypedObject(T, int), writeTypedArray(T[], int), writeTypedList(List), readTypedObject(Parcelable.Creator),createTypedArray(Parcelable.Creator),createTypedArrayList(Parcelable.Creator),这些方法不传递原始对象的类信息,读函数的调用者要知道期望读出的类型,并传入Parcelable.Creator读取信息。更高效的是:当读写单个非空Parcelable对象时,调用Parcelable.writeToParcel, Parcelable.Creator.createFromParcel。
Bundles
Bundle是一个类型安全的包裹类,存储键/值对,其中值可以是各种各样类型的。这对提高读写性能有很大优化。在把数据组装进Parcel时,它的类型安全API可以避免调试类型错误。writeBundle(Bundle), readBundle(),readBundle(ClassLoader)。
Active Objects
Parcel一个不经常用的功能是读写active objects。这种对象的实际内容并没有写入Parcel,而是将代表这个对象的一个特殊的token写入。当从Parcel中读取该对象的时候,并非得到该对象的一个新的实例,而是一个手柄,这一手柄直接在原始对象上操作。有两种active objects。
Binder是Android进程间通信的核心功能对象。IBinder接口定义了一系列Binder操作的协议。任何这种接口都可以写入Parcel,读的时候你得到的或者是实现了该接口的原始对象,或者是原始对象的专门的代理,用代理来调用原始对象。writeStrongBinder(IBinder),writeStrongInterface(IInterface), readStrongBinder(), writeBinderArray(IBinder[]), readBinderArray(IBinder[]), createBinderArray(), writeBinderList(List), readBinderList(List),createBinderArrayList()。
FileDescriptor对象,写入,读出。读出的对象ParcelFileDescriptor是对原始文件描述符的dup:对象和fd不同,但操作的是同一个文件。writeFileDescriptor(FileDescriptor), readFileDescriptor()。
隐式类型
标准Java的任意类型数据。writeValue(Object),readValue(ClassLoader), writeArray(Object[]), readArray(ClassLoader)
Parcelable
Parcelable是一个接口,实现了这个接口的类实例可以通过Parcel传输。实现该接口的类必须有一个非空静态域CREATOR,CREATOR实现接口Parcelable.Creator。
一个典型的例子:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}