Android初学之Parcel和Parcelable

最近在看项目源码的时候经常看到Parcel和Parcelable的字眼,所以花了点时间了解一下。

Parcel


Parcel是一个用于包装各种数据的容器类,凡是经过Parcel包装后的数据都可以通过在binder进程间通信IPC中进行服务端和数据端的数据交互,AIDL中也用到了Parcel进行数据封装。
现在简单介绍一下,使用Parcel包装后进程间通信的工作大致的原理:
假如有进程A、B需要进行通信,在进程A中用Parcel将需要传输的数据类中的飞默认值和唯一类标识打包(此过程称为序列化),再把这个包传输到进程B中,进程B通过这个包中的唯一标示将会重新创建一个一模一样的类对象,这就是通信的大概过程。
虽然,parcel在网上是这么被描述的,但是对于初学Android的我来说还是不懂,所以就去看了一下源码部分。


Parcel is not a general-purpose
serialization mechanism.  This class (and the corresponding
{@link Parcelable} API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport.

从上面可以看出,parcel不是一般用途的序列化机制,这个类以及与之相匹配的Parcelable接口(Parcelable能够将任意的对象打包进parcel实例中)使IPC数据传输更加的高效。

另外,Parcel类中的核心部分涉及了不同数据类型到parcel对象的读写的实现。其中,基本类型(long、int、String、double等)是可以直接进行打包或者读取的,但是自定义的类型必须在实现了Parcelable后才能进行打包。

看到的几个应该注意的点:
1)obtain()和recycle()方法,一个类似于new一个parcel对象,一个回收一个parcel对象。
2)涉及Map的write或者read操作,一般的推荐使用writeBundle和readBundle,因为readMap或者writeMap方法的花销要比前者大的多,所以不推荐使用。
3)dataSize()和dataCapacity()的含义有所区别:前者表示实际大小,后者表示一个parcel分配到的大小,一般是大于dataSize的。

另外:源码中几乎都是readXXXX和writeXXXX的方法,这也说明了parcel的功能和他的地位。

Parcelable

字面意义上来讲,是一个使对象能够parcel的接口。上面的描述中,我们提到了parcel如果想要打包自定义的数据结构,那么这个自定义的类必须实现Parcelable的方法。所以,我们可以这么理解Parcelable:他是一个使自定义类对象具有序列化能力的接口,凡是实现了该接口的类对象都能够被parcel。

Parcelable中有两个使自定义类具备parcel能力的方法(接口):
1)public void writeToParcel(Parcel dest,int flags),实现这个方法又该如何做呢?我们知道哪怕是自定义类,他的成员最终也会是基本类型,所以我们只需要将每一个基本类型的成员属性利用dest.writeXXXX打包进Parcel dest中去。而非基本类型的自定义成员属性,我们可以继续实现Parcelable接口。

2)public interface Creator< T >,其中包含两个方法:public T createFromParcel(Parcel source)和public T[] newArray(int size)。
用于从Parcel中取出指定的数据类型。


你可能感兴趣的:(学习日志)