一,什么是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;
}