Linux系統中處理序間通訊的方式有:socket, named pipe,message queque, signal,share memory。Java系統中的處理序間通訊方式有socket,
named pipe等,android應用程式理所當然可以應用JAVA的IPC機制實現進程間的通訊,但我查看android的源碼,在同一終端上的應用軟體的通
信幾乎看不到這些IPC通訊方式,取而代之的是Binder通訊。Google為什麼要採用這種方式呢,這取決於Binder通訊方式的高效率。Binder通訊是通過linux的binder
driver來實現的,Binder通訊操作類似線程遷移(thread migration),兩個進程間IPC看起來就象是一個進程進入另一個進程執行代碼然後帶著執行的結果返回。Binder的使用者空間為每一個進程維護著
一個可用的線程池,線程池用於處理到來的IPC以及執行進程本地訊息,Binder通訊是同步而不是非同步。
Android中的Binder通訊是基於Service與Client的,所有需要IBinder通訊的進程都必須建立一個IBinder介面,系統中
有一個進程管理所有的system service,Android不允許使用者添加非授權的System service,當然現在源碼開發了,我們可以修改一些代碼來實現添加底層system
Service的目的。對使用者程式來說,我們也要建立server,或者Service用於處理序間通訊,這裡有一個ActivityManagerService管理JAVA應用程式層所有的service建立與串連(connect),disconnect,所有的Activity也是通過這個service來啟動,載入的。ActivityManagerService也是載入在Systems
Servcie中的。
Android虛擬機器啟動之前系統會先啟動service Manager進程,service Manager開啟binder驅動,並通知binder
kernel驅動程式這個進程將作為System Service Manager,然後該進程將進入一個迴圈,等待處理來自其他進程的資料。使用者建立一個System service後,通過defaultServiceManager得到一個遠程ServiceManager的介面,通過這個介面我們可以調用addService函數將System
service添加到Service Manager進程中,然後client可以通過getService擷取到需要串連的目的Service的IBinder對象,這個IBinder是Service的BBinder在binder
kernel的一個參考,所以service IBinder
在binder kernel中不會存在相同的兩個IBinder對象,每一個Client進程同樣需要開啟Binder驅動程式。對使用者程式而言,我們獲得這個對象就可
以通過binder kernel訪問service對象中的方法。Client與Service在不同的進程中,通過這種方式實現了類似線程間的遷移的通訊方式,對使用者程式
而言當調用Service返回的IBinder介面後,訪問Service中的方法就如同調用自己的函數。
首先從ServiceManager註冊過程來逐步分析上述過程是如何?的。
ServiceMananger進程註冊過程源碼分析:
Service Manager Process(Service_manager.c):
Service_manager為其他進程的Service提供管理,這個服務程式必須在Android Runtime起來之前運行,否則Android
JAVA Vm ActivityManagerService無法註冊。
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024); //開啟/dev/binder驅動
if (binder_become_context_manager(bs)) {//註冊為service manager in binder kernel
LOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);
return 0;
}
首先開啟binder的驅動程式然後通過binder_become_context_manager函數調用ioctl告訴Binder
Kernel驅動程式這是一個服務管理進程,然後調用binder_loop等待來自其他進程的資料。BINDER_SERVICE_MANAGER是服
務管理進程的控制代碼,它的定義是:
/* the one magic object */
#define BINDER_SERVICE_MANAGER ((void*) 0)
如果用戶端進程擷取Service時所使用的控制代碼與此不符,Service Manager將不接受Client的請求。