1.IPC解决方案 而非 序列化机制
Container for a message (data and object references) that can be sent through an IBinder. A Parcel can contain both flattened
data that will be unflattened on the other side of the IPC (using the various methods here for writing specific types, or the general
Parcelable
interface), and references to live IBinder
objects that will result in the other side receiving a proxy IBinder connected with
the original IBinder in the Parcel.
Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable
API for placing arbitrary
objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to
persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.
2.指针移动
public final native int dataSize(); public final native int dataAvail(); public final native int dataPosition(); public final native int dataCapacity(); public final native void setDataSize(int size); public final native void setDataPosition(int pos); public final native void setDataCapacity(int size);
3.读写数据
Parcel parcel = Parcel.obtain(); parcel.writeInt(1); parcel.writeInt(2); parcel.writeInt(3); //不调用parcel.setDataPosition(i)读不出实际内容 //System.out.println("----------------" + parcel.readInt()); int size = parcel.dataSize(); Log.d("parcel", "--------- " + size); int i = 0; while (i <= size ) { parcel.setDataPosition(i); int cur = parcel.readInt(); Log.d("parcel", "--------- " + cur); i+=4; }
4.marshall & unmarshall
public final native byte[] marshall();
- Returns the raw bytes of the parcel.
- The data you retrieve here must not be placed in any kind of persistent storage (on local disk, across a network, etc). For that,
you should use standard serialization or another kind of general serialization mechanism. The Parcel marshalled representation
is highly optimized for local IPC, and as such does not attempt to maintain compatibility with data created in different
versions of the platform.
public final native void unmarshall(byte[] data, int offest, int length);
- Set the bytes in data to be the raw bytes of this Parcel.
作用类似于序列化和反序列化。即将当前Parcel的数据序列化为byte数组,或者将byte数组反序列化到当前Parcel中。
注:unmarshall后,如果要读取数据,首先需要将文件指针移动到初始化位置,即setDataPosition(0)。
5.工具
public class ParcelableUtil { public static byte[] marshall(Parcelable parceable) { Parcel parcel = Parcel.obtain(); parceable.writeToParcel(parcel, 0); byte[] bytes = parcel.marshall(); parcel.recycle(); // notice return bytes; } public static Parcel unmarshall(byte[] bytes) { Parcel parcel = Parcel.obtain(); parcel.unmarshall(bytes, 0, bytes.length); parcel.setDataPosition(0); // this is extremely important! return parcel; } public static <T> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) { Parcel parcel = unmarshall(bytes); return creator.createFromParcel(parcel); } }
3.
With the help of the util class above, you can marshall/unmarshall instances of your class MyClass implements Parcelable like so: //Unmarshalling (with CREATOR) byte[] bytes = … MyClass myclass = ParcelableUtil.unmarshall(bytes, MyClass.CREATOR);
//Unmarshalling (without CREATOR) byte[] bytes = … Parcel parcel = ParcelableUtil.unmarshall(bytes); MyClass myclass = new MyClass(parcel); // or MyClass.CREATOR.createFromParcel(parcel)
//Marshalling MyClass myclass = … byte[] bytes = ParcelableUtil.marshall(myclass);