一,什么是IPC
IPC:inter-process communication,进程间通信或者跨进程通信。window通过剪贴板,管道等进行进程间通信。Linux通过命名管道,共享内存,信号量等进行进程间通信。android有特色的是Binder。在android进程通信可以有以下方式:aidl,socket通信,使用Bundle,使用contentprovider,使用Messenger,使用文件共享。
二,android的序列化
在android中能用于进程间通信的对象必须是序列化的。序列的方式有两种,一种是实现Serializable接口,一种是实现Parcelable。Serializable是java提供的序列化方法,实现很简单,只要一个类实现了它就完成了序列化。可用于将对象序列化到存储设备或序列化后通过网络传输。但它的效率不高,这里重点介绍Parcelable,它是android自己的实现序列化方法,先看实现Parcelable的代码:
只要一个类实现了这个接口,就可以实现序列化并可以通过Intent和Binder传递。要实现以下方法
(1).writeToParcel(out,flags):实现序列化功能,一系列write。如下
out.writeInt(userId);
out.writeParcelable(book,0);//传另一个序列化类
(2).CREATOR:反序列化,一系列的read方法:如下
userId = in.readInt();
book = in.readParcelable(Thread.currentThread().getContextClassLoader());
(3).decribeContents:内容描述,几乎所有情况都返回0.
系统还提供了一些实现了Parcelable接口的类,如Intent,Bundle,Bitmap.同时List和Map也可以序列化,前提是它们里所有元素都 可以序列化。
Parcelable效率比Serializable高,在内存序列化上用它合适。但在将对象序列化到存储设备或序列化后通过网络传输则建议用Serializable,比较方便。
二,Binder的介绍
Binder用于完成进程间的通信(IPC)。Binder是工作在Linux层,属于一个驱动,这个驱动不需要驱动,Binder代码运行在内核态,调用Binder是系统进行调用。
Binder是一种架构,这种架构提供服务端接口,Binder 接口,客户端接口三个模块。一个Binder 服务端就是一个Binder对象,该对象一旦创建,就会启动一个隐藏线程,该线程会接Binder 驱动发送的消息。收到消息会发调用 onTransact()方法,并按照参数执行不同的服务代码,onTransact() 的参数来源是客户端调用 transact(),若transact() 有固定的输入,onTransact()就有固定的输出
。
一个服务端被创建,会创建一个mRemote对象,它的类型也是Binder类,客户端要访问远程时是通过它。它也重载了transact()方法,重载内容如下:
1,以线程消息通信模式,向服务端发送客户端传递过来的参数。
2.挂起当前线程,并等待服务端线程执行完指定服务函数后通知。
3.接收服务端通知并执行客户端线程,并返回到客户端代码区。
它的调用图如下:
AIDL 是什么
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
如何使用AIDL ?
大致流程:首先创建一个Service 和一个AIDL接口,接着创建一个继承自AIDL接口中的Stub 类,并实现Stub中的抽象方法,在Service的onBind 方法中返回这个类的对象,然后客户端就会绑定服务端的Service,建立连接后就可以访问远程服务端的方法了。
Messenger进程间通信
android提供Messenger可以实现不同进程间的信息传递,相比AIDL它的调用简单很多,但是它是有缺点的,它只能串行处理发送的信息,如里信息过多就会阻塞。其次它只能传输基本数据类型,What,arg1,Bundle等,并不能传输自定义的对象。Messenger是一种种轻量级的IPC方案,一次处理一个请求。
如何选用合适的IPC方式
Bundle — 优点:简单易用— 缺点:只能传输Bundle支持的数据类型— 适用场景:四大组件间的进程通信
文件共享—优点:简单易用—缺点:不适合高并发场景,并且无法做到进程间的即时通信— 适用场景:无并发访问的场景,交换简单的数据实时性不高的场景
AIDL—优点:功能强大,支持一对多并发通信,支持实时通信— 缺点:使用稍复杂,需要处理好线程同步— 适用场景:一对多通信,且有RPC需求
Messenger —优点:功能一般,支持一对多串行通信,支持实时通信— 缺点:不能很好处理高并发的情形不支持RPC,数据通过Message进行传输,因此只能传输Bundle支持的数据类型 ,适用场景:低并发的一对多即时通信,无RPC要求,或者无需要返回结果的RPC需求。
ContentProvider —优点:在数据访问方面功能强大,支持一对多并发数据共享,可以通过call方法扩展其他操作— 缺点:可以理解为受约束的AIDL,主要提供数据源的CRUD操作,— 使用场景:一对多的进程间的数据共享
Socket–优点:功能强大,可以通过网络传输字节流,支持一对多并发实时通信—-缺点:实现细节稍微有点繁琐,不支持直接的RPC—-适用场景: 网络数据交换