一,什么是IPC
IPC:inter-process communication,进程间通信或者跨进程通信。window通过剪贴板,管道等进行进程间通信。Linux通过命名管道,共享内存,信号量等进行进程间通信。android有特色的是Binder。在android进程通信可以有以下方式:aidl,socket通信,使用Bundle,使用contentprovider,使用Messenger,使用文件共享
二 binder 机制
我们知道,在Android app中的众多activity,service等组件可以运行在同一进程中,也可以运行在不同进程中。当组件运行在同一进程中进行通信就显得比较简单,在之前的Android线程间通信机制中已经讲过了;而当它们运行在不同的进程 中时,就需要使用我们本文中所要介绍的Binder机制了。
Binder作为一种进程间通信机制,负责提供远程调用的功能(RPC),它的系统组件主要包括四种:Client, Server, ServiceManager, Binder Driver. 它们之间的关系如下图所示
从图中我们可以看出,Client, Server, ServiceManager运行在系统的用户态,而Binder Driver运行在内核态。为了完成Client端到Server端的通信任务,用户空间的需要操作Binder Driver提供的/dev/binder文件来完成交互。那么ServiceManager的工作是什么呢?ServiceManager负责管理Server并向Client端提供一个Server的代理接口(proxy)。通过代理接口中定义的方法,Client端就可以使用Server端提供的服务了。整个过程如下:
Client端调用代理接口的方法,将Client的参数打包为parcel对象发送给内核空间中BinderDriver;
Server端读取到BinderDriver中的请求数据,将parcel对象解包并处理;
处理好后,将处理结果打包返回给BinderDriver,再交给Client端。
另外,Client端与Server端的调用过程是同步的,即在Server返回结果之前,Client端是阻塞的。调用过程如下所示:
AIDL 例子
首先定义一个AIDL 文件,名字ICalculateAidlInterface.aidl , 定义两个方法,重新rebuild下工厂,则生成对应的Java文件,Java文件位于/build/generated/source/aidl/debug/包名/
interface ICalculateAidlInterface {
int add(int a,int b);
int minus(int a,int b);
}
然后新建一个CalculateService 继承Service 做服务端 ,顺便打印Service 生命周期
@Overridepublic void onCreate() {
Log.e(TAG,"onCreate");
super.onCreate();
}
@Overridepublic void onStart(Intent intent, int startId) {
Log.e(TAG,"onStart");
super.onStart(intent, startId);
}
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG,"onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Overridepublic void onDestroy() {
Log.e(TAG,"onDestroy");
super.onDestroy();
}
@Overridepublic boolean onUnbind(Intent intent) {
Log.e(TAG,"onUnbind");
return super.onUnbind(intent);
}
@Overridepublic void onRebind(Intent intent) {
Log.e(TAG,"onRebind");
super.onRebind(intent);
}
@Nullable@Overridepublic IBinder onBind(Intent intent) {
Log.e(TAG,"onBind"); return mBinder;
}