打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Parcel
userphoto

2015.05.16

关注
frameworks/native/libs/binder/Parcel.cpp

core/jni/android_os_Parcel.cpp

core/java/android/os/ParcelFileDescriptor.java
core/java/android/os/Parcel.java

 那么到底如何在进程之间传递类对象呢?简单来说可以这样做:在进程A中把类中的非默认值的属性和类的唯一标志打成包(这就叫序列化),把这个包传递到 进程B,进程B接收到包后,跟据类的唯一标志把类创建出来,然后把传来的属性更新到类对象中,这样进程A和进程B中就包含了两个完全一样的类对象。

Parcel是一个容器,它主要用于存储序列化数据,然后可以通过Binder在进程间传递这些数据(要了解为什么要序列化,请参 考:http://blog.csdn.net/nkmnkm/archive/2011/05/28/6451699.aspx)。
1、Parcel可以包 含原始数据类型(用各种对应的方法写入,比如writeInt(),writeFloat()等)
2、可以包含Parcelable对象,它还包含了一个活 动的IBinder对象的引用,这个引用导致另一端接收到一个指向这个IBinder的代理IBinder。 

注:Parcel不是一般目的的序列化机制。这个类被设计用于高性能的IPC传输。因此不适合把Parcel写入永久化存储中,因为Parcel中的数据类型的实现的改变会导致旧版的数据不可读。

  Parcel的一坨一坨的API用于解决不同类型数据的读写。这些函数们主要有六种类型。

1原始类

这类方法们主要读写原始数据类型。它们是:writeByte(byte), readByte(), writeDouble(double), readDouble(), writeFloat(float), readFloat(), writeInt(int), readInt(), writeLong(long), readLong(), writeString(String), readString(). 大多数其它数据的操作都是基于这些方法。

2原始数组类

这类方法用于读写原始数据组成的数组。在向数组写数据时先写入数组的长度再写入数据。读数组的方法可以将数据读到已存在的数组中,也可以创建并返回一个新数组。它们是:

writeBooleanArray(boolean[]), readBooleanArray(boolean[]), createBooleanArray() 
writeByteArray(byte[]), writeByteArray(byte[], int, int), readByteArray(byte[]), createByteArray() 
writeCharArray(char[]), readCharArray(char[]), createCharArray() 
writeDoubleArray(double[]), readDoubleArray(double[]), createDoubleArray() 
writeFloatArray(float[]), readFloatArray(float[]), createFloatArray() 
writeIntArray(int[]), readIntArray(int[]), createIntArray() 
writeLongArray(long[]), readLongArray(long[]), createLongArray() 
writeStringArray(String[]), readStringArray(String[]), createStringArray(). 
writeSparseBooleanArray(SparseBooleanArray), readSparseBooleanArray(). 
3 Parcelable类 
Parcelable为对象从Parcel中读写自己提供了极其高效的协议。你可以使用直接的方法 writeParcelable(Parcelable, int) 和 readParcelable(ClassLoader) 或 writeParcelableArray(T[], int) and readParcelableArray(ClassLoader) 进行读写。这些方法们把类的信息和数据都写入Parcel,以使将来能使用合适的类装载器重新构造类的实例。

还有一些方法提供了更高效的操作Parcelable们的途径,它们是:writeTypedArray(T[], int), writeTypedList(List), readTypedArray(T[], Parcelable.Creator) and readTypedList(List, Parcelable.Creator)。这些方法不会写入类的信息,取而代之的是:读取时必须能知道数据属于哪个类并传入正确的 Parcelable.Creator来创建对象而不是直接构造新对象。(更加高效的读写单个Parcelable对象的方法是:直接调用 Parcelable.writeToParcel()和Parcelable.Creator.createFromParcel())

4 Bundles类

Bundles是一种类型安全的Map型容器,可用于存储任何不同类型的数据。它具有很多对讀写数据的性能优化,并且它的类型安全机制避免了当把它的数据封送到Parcel中时由于类型错误引起的BUG的调试的麻烦,可以使用的方法为: writeBundle(Bundle), readBundle(), and readBundle(ClassLoader)。

5 活动对象类

Parcel的一个非同寻常的特性是读写活对象的能力。对于活动对象,它们的内容实际上并没有写入,而是仅写入了一个令牌来引用这个对象。当从Parcel中读取这个对象时,你不会获取一个新的对象实例,而是直接得到那个写入的对象。有两种活动对象可操作:

Binder对象。它是Android跨进程通讯的基础。这种对象可被写入Parcel,并在读取时你将得到原始的对象或一个代理对象(可以想象:在进程内时得到原始的对象,在进程间时得到代理对象)。可以使用的方法们是: writeStrongBinder(IBinder), writeStrongInterface(IInterface), readStrongBinder(), writeBinderArray(IBinder[]), readBinderArray(IBinder[]), createBinderArray(), writeBinderList(List), readBinderList(List), createBinderArrayList()。

FileDescriptor对象。它代表了原始的Linux文件描述符,它可以被写入Parcel并在读取时返回一个 ParcelFileDescriptor对象用于操作原始的文件描述符。ParcelFileDescriptor是原始描述符的一个复制:对象和fd 不同,但是都操作于同一文件流,使用同一个文件位置指针,等等。可以使用的方法 是:writeFileDescriptor(FileDescriptor), readFileDescriptor()。

6无类型容器类

    一类final方法,用于读写标准的java容器类。这些方法们是:writeArray(Object[]), readArray(ClassLoader), writeList(List), readList(List, ClassLoader), readArrayList(ClassLoader), writeMap(Map), readMap(Map, ClassLoader), writeSparseArray(SparseArray), readSparseArray(ClassLoader)。

什么是Pending intent 
Pending描述了一个Intent和intent的动作。这个类的实例是用getActivity(Context,int,Intent,int) 方法和getBroadcast(Context,int,Intent,int)和 getService(Context,int,Intent,int)方法创建的。创建出的pending intent可以交给其它程序,于是它们可以在以后的某个时间以你的名义执行intent中所描述的动作。
 

通过给于一个PendingIntent,你可以使其它程序像你自己一样执行你所指定的操作(具有相同的权限和身份)。所以,你需要小心的创建 PendingIntent:通常,你最基本的应该明确设置你的相关组件的名字,以保证将来intent是被发送给它而不是其它地方。
 

一个PendingIntent本是只是简单地引用一个由系统维护的一个令牌,这个令牌描述了用于取得PendingIntent的原始数据。这表示即使 拥有这个PendingIntent的进程关闭了,但这个PendingIntent对于那些收到它的进程依然有效。如果创建这个 PendingIntent的程序又重新运行并重新获取同一个类型的PendingIntent(相同的操作,action,数据,类型和组件以及相同的 标志),那么获取的还是这个PendingIntent,并且这个程序可以用cancel()来删除这个PendingIntent。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android开发:什么是IBinder
activity和service之间的相互通信方法
使用AIDL实现进程间的通信之复杂类型传递
4.2.3 Service精通
Binder源码分析之Java层(原)
Binder基本概念流程学习
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服