Android源码之Parcel.docx

上传人:b****6 文档编号:3045655 上传时间:2022-11-17 格式:DOCX 页数:4 大小:17.41KB
下载 相关 举报
Android源码之Parcel.docx_第1页
第1页 / 共4页
Android源码之Parcel.docx_第2页
第2页 / 共4页
Android源码之Parcel.docx_第3页
第3页 / 共4页
Android源码之Parcel.docx_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Android源码之Parcel.docx

《Android源码之Parcel.docx》由会员分享,可在线阅读,更多相关《Android源码之Parcel.docx(4页珍藏版)》请在冰豆网上搜索。

Android源码之Parcel.docx

Android源码之Parcel

Android源码之Parcel

Parcel的意思是“打包”。

在Android中,Parcel的作用类似于Java中的serialize,即对象的序列化。

Android系统定位为内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC机制,必然要求使用性能更出色的对象传输方式。

在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。

Parcel的最主要作用是在各个activity之间传递数据。

Android开发中,很经常在各activity之间传递数据,而跟据Android的设计架构,即使同一个程序中的Activity都不一定运行在同一个进程中,所以处理数据传递时你不能老假设两个activity都运行于同一进程,那么只能按进程间传递数据来处理,使之具有最广泛的适应性。

Parcel的接口主要有以下几类:

一、Parcel的获取与释放

[java]viewplaincopypublicstaticParcelobtain(){finalParcel[]pool=sOwnedPool;synchronized(pool){Parcelp;for(inti=0;i<POOL_SIZE;i++){p=pool[i];if(p!

=null){pool[i]=null;if(DEBUG_RECYCLE){p.mStack=newRuntimeException();}returnp;}}}returnnewParcel(0);}publicfinalvoidrecycle(){if(DEBUG_RECYCLE)mStack=null;freeBuffer();finalParcel[]pool=mOwnObject!

=0?

sOwnedPool:

sHolderPool;synchronized(pool){for(inti=0;i<POOL_SIZE;i++){if(pool[i]==null){pool[i]=this;return;}}}}

获取接口obtain是从一个已分配的Parcel池中取得一个Parcel,即sOwnedPool,其定义如下:

[java]viewplaincopyprivatestaticfinalintPOOL_SIZE=6;privatestaticfinalParcel[]sOwnedPool=newParcel[POOL_SIZE];privatestaticfinalParcel[]sHolderPool=newParcel[POOL_SIZE];

当使用完获得的Parcel后,最好使用recycle将其释放回池,以便下次使用,否则导致Parcel池无可分配资源而new新对象。

幸运的是,eclipse会给出此类的警告提示。

二、Parcel内部指针的移动

[java]viewplaincopypublicfinalnativeintdataSize();publicfinalnativeintdataAvail();publicfinalnativeintdataPosition();publicfinalnativeintdataCapacity();publicfinalnativevoidsetDataSize(intsize);publicfinalnativevoidsetDataPosition(intpos);publicfinalnativevoidsetDataCapacity(intsize);

由于Parcel的读写是直接在内存中的,所以这几个接口就是指示当前的读写指针,类似于Linux下的文件读写操作:

dataSize:

返回当前内存块中总共的数据

dataPosition:

返回当前读操作指针

dataAvail:

返回当前可读的数据,即dataSize-dataPosition

dataCapacity:

返回当前内存块的容量(在不重新分配内存的前提下),dataCapacity-dataSize即为可写入的数据量三、数据读写类

1、序列化与反序列化

publicfinalnativebyte[]marshall();

publicfinalnativevoidunmarshall(byte[]data,intoffest,intlength);

作用类似于序列化和反序列化。

即将当前Parcel的数据序列化为byte数组,或者将byte数组反序列化到当前Parcel中。

注:

unmarshall后,如果要读取数据,首先需要将文件指针移动到初始化位置,即setDataPosition(0)。

2、基本数据类型的读写

privatenativevoidwriteNative(byte[]

b,intoffset,intlen);

publicfinalnativevoidwriteInt(intval);

publicfinalnativevoidwriteLong(longval);

publicfinalnativevoidwriteFloat(floatval);

publicfinalnativevoidwriteDouble(doubleval);

publicfinalnativevoidwriteString(Stringval);

publicfinalnativevoidwriteStrongBinder(IBinderval);

publicfinalnativevoidwriteFileDescriptor(FileDescriptorval);publicfinalnativeintreadInt();

publicfinalnativelongreadLong();

publicfinalnativefloatreadFloat();

publicfinalnativedoublereadDouble();

publicfinalnativeStringreadString();

publicfinalnativeIBinderreadStrongBinder();全部都是native方法,通过JNI来调用底层实现。

其余类型的读写都是在基本数据类型的基础上得来的。

如:

[java]viewplaincopypublicfinalvoidwriteByte(byteval){writeInt(val);}publicfinalbytereadByte(){return(byte)(readInt()&0xff);}

可见,byte在Parcel中也占用四个字节。

3、Array类型的读写

Array类型的接口按类型来分,如boolean[]/char[]/int[]/float[]/double[]/String[],而每一种类型都包含三个接口:

publicfinalvoidwriteXXXArray(boolean[]val);publicfinalboolean[]createXXXArray();publicfinalvoidreadXXXArray(boolean[]val);以boolean类型为例:

其源码如下:

[java]viewplaincopypublicfinalvoidwriteBooleanArray(boolean[]val){if(val!

=null){intN=val.length;writeInt(N);for(inti=0;i<N;i++){writeInt(val[i]?

1:

0);}}else{writeInt(-1);}}publicfinalboolean[]createBooleanArray(){intN=readInt();//>>2asafastdivide-by-4worksinthecreate*Array()functions//becausedataAvail()willneverreturnanegativenumber.4is//thesizeofastoredbooleaninthestream.if(N>=0&&N<=(dataAvail()>>2)){boolean[]val=newboolean[N];for(inti=0;i<N;i++){val[i]=readInt()!

=0;}returnval;}else{returnnull;}}publicfinalvoidreadBooleanArray(boolean[]val){intN=readInt();if(N==val.length){for(inti=0;i<N;i++){val[i]=readInt()!

=0;}}else{thrownewRuntimeException("badarraylengths");}}

可见,其write操作的过程是先以整形的方式写入Array的长度,然后依次写入Array的每一个元素。

而读操作的过程则正好相反。

注:

从以上示例看出,boolean类型在Parcel中也占据四个字节。

4、通用接口

[java]viewplaincopypublicfinalvoidwriteValue(Objectv){if(v==null){writeInt(VAL_NULL);}elseif(vinstanceofString){writeInt(VAL_STRING);writeString((String)v);}elseif(vinstanceofInteger){writeInt(VAL_INTEGER);writeInt((Integer)v);}elseif(vinstanceofMap){writeInt(VAL_MAP);writeMap((Map)v);}elseif(vinstanceofBundle){//MustbebeforeParcelablewriteInt(VAL_BUNDLE);writeBundle((Bundle)v);}elseif(vinstanceofParcelable){writeInt(VAL_PARCELABLE);writeParcelable((Parcelable)v,0);}elseif(vinstanceofShort){writeInt(VAL_SHORT);writeInt(((Short)v).intValue());}elseif(vinstanceofLong){writeInt(VAL_LONG);writeLong((Long)v);}elseif(vinst

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1