1、Android源码之ParcelAndroid源码之Parcel Parcel的意思是“打包”。在Android中,Parcel的作用类似于Java中的serialize,即对象的序列化。Android系统定位为内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC机制,必然要求使用性能更出色的对象传输方式。在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。Parcel的最主要作用是在各个activity之间传递数据。Android开发中,很经常在各activity之间传递数据,而跟据Android的设计架构,即使同一个程序中的Activity都
2、不一定运行在同一个进程中,所以处理数据传递时你不能老假设两个activity都运行于同一进程,那么只能按进程间传递数据来处理,使之具有最广泛的适应性。Parcel的接口主要有以下几类:一、Parcel的获取与释放java view plaincopypublic static Parcel obtain() final Parcel pool = sOwnedPool; synchronized (pool) Parcel p; for (int i=0; i<POOL_SIZE; i+) p = pooli; if (p != null) pooli = null; if (DEBUG
3、_RECYCLE) p.mStack = new RuntimeException(); return p; return new Parcel(0); public final void recycle() if (DEBUG_RECYCLE) mStack = null; freeBuffer(); final Parcel pool = mOwnObject != 0 ? sOwnedPool : sHolderPool; synchronized (pool) for (int i=0; i<POOL_SIZE; i+) if (pooli = null) pooli = thi
4、s; return; 获取接口obtain是从一个已分配的Parcel池中取得一个Parcel,即sOwnedPool,其定义如下:java view plaincopyprivate static final int POOL_SIZE = 6; private static final Parcel sOwnedPool = new ParcelPOOL_SIZE; private static final Parcel sHolderPool = new ParcelPOOL_SIZE; 当使用完获得的Parcel后,最好使用recycle将其释放回池,以便下次使用,否则导致Parcel
5、池无可分配资源而new新对象。幸运的是,eclipse会给出此类的警告提示。二、Parcel内部指针的移动java view plaincopypublic 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 se
6、tDataPosition(int pos); public final native void setDataCapacity(int size); 由于Parcel的读写是直接在内存中的,所以这几个接口就是指示当前的读写指针,类似于Linux下的文件读写操作:dataSize:返回当前内存块中总共的数据dataPosition:返回当前读操作指针dataAvail:返回当前可读的数据,即dataSize - dataPositiondataCapacity:返回当前内存块的容量(在不重新分配内存的前提下),dataCapacity - dataSize即为可写入的数据量三、数据读写类1、序
7、列化与反序列化public final native byte marshall();public final native void unmarshall(byte data, int offest, int length);作用类似于序列化和反序列化。即将当前Parcel的数据序列化为byte数组,或者将byte数组反序列化到当前Parcel中。注:unmarshall后,如果要读取数据,首先需要将文件指针移动到初始化位置,即setDataPosition(0)。2、基本数据类型的读写private native void writeNative(byteb, int offset, in
8、t len);public final native void writeInt(int val);public final native void writeLong(long val);public final native void writeFloat(float val);public final native void writeDouble(double val);public final native void writeString(String val);public final native void writeStrongBinder(IBinder val);publ
9、ic final native void writeFileDescriptor(FileDescriptor val);public final native int readInt();public final native long readLong();public final native float readFloat();public final native double readDouble();public final native String readString();public final native IBinder readStrongBinder();全部都是
10、native方法,通过JNI来调用底层实现。其余类型的读写都是在基本数据类型的基础上得来的。如:java view plaincopypublic final void writeByte(byte val) writeInt(val); public final byte readByte() return (byte)(readInt() & 0xff); 可见,byte在Parcel中也占用四个字节。3、Array类型的读写Array类型的接口按类型来分,如boolean/char/int/float/double/String,而每一种类型都包含三个接口:public fina
11、l void writeXXXArray(boolean val);public final boolean createXXXArray();public final void readXXXArray(boolean val);以boolean类型为例:其源码如下:java view plaincopypublic final void writeBooleanArray(boolean val) if (val != null) int N = val.length; writeInt(N); for (int i=0; i<N; i+) writeInt(vali ? 1 : 0
12、); else writeInt(-1); public final boolean createBooleanArray() int N = readInt(); / >>2 as a fast divide-by-4 works in the create*Array() functions / because dataAvail() will never return a negative number. 4 is / the size of a stored boolean in the stream. if (N >= 0 && N <= (d
13、ataAvail() >> 2) boolean val = new booleanN; for (int i=0; i<N; i+) vali = readInt() != 0; return val; else return null; public final void readBooleanArray(boolean val) int N = readInt(); if (N = val.length) for (int i=0; i<N; i+) vali = readInt() != 0; else throw new RuntimeException(ba
14、d array lengths); 可见,其write操作的过程是先以整形的方式写入Array的长度,然后依次写入Array的每一个元素。而读操作的过程则正好相反。注:从以上示例看出,boolean类型在Parcel中也占据四个字节。4、通用接口java view plaincopypublic final void writeValue(Object v) if (v = null) writeInt(VAL_NULL); else if (v instanceof String) writeInt(VAL_STRING); writeString(String) v); else if (
15、v instanceof Integer) writeInt(VAL_INTEGER); writeInt(Integer) v); else if (v instanceof Map) writeInt(VAL_MAP); writeMap(Map) v); else if (v instanceof Bundle) / Must be before Parcelable writeInt(VAL_BUNDLE); writeBundle(Bundle) v); else if (v instanceof Parcelable) writeInt(VAL_PARCELABLE); writeParcelable(Parcelable) v, 0); else if (v instanceof Short) writeInt(VAL_SHORT); writeInt(Short) v).intValue(); else if (v instanceof Long) writeInt(VAL_LONG); writeLong(Long) v); else if (v inst
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1