Binder -- 一種進程間通信(IPC)機制, 基於OpenBinder來實現
毫無疑問, 老羅的文章是不得不看的
Android進程間通信(IPC)機制Binder簡要介紹和學習計划
淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路
淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
Android系統進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析
Android系統進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析
Android系統進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
提供遠程過程調用(RPC)功能
先來認識一下Binder是干嘛的
Android系統Binder機制中的四個組件Client、Server、Service Manager和Binder驅動程序的關系如下圖所示:
1. Client、Server和Service Manager實現在用戶空間中,Binder驅動程序實現在內核空間中
2. Binder驅動程序和Service Manager在Android平台中已經實現,開發者只需要在用戶空間實現自己的Client和Server
3. Binder驅動程序提供設備文件/dev/binder與用戶空間交互,Client、Server和Service Manager通過open和ioctl文件操作函數與Binder驅動程序進行通信
4. Client和Server之間的進程間通信通過Binder驅動程序間接實現
5. Service Manager是一個守護進程,用來管理Server,並向Client提供查詢Server接口的能力
至此,對Binder機制總算是有了一個感性的認識,但仍然感到不能很好地從上到下貫穿整個IPC通信過程,於是,打算通過下面四個情景來分析Binder源代碼,以進一步理解Binder機制:
1. Service Manager是如何成為一個守護進程的?即Service Manager是如何告知Binder驅動程序它是Binder機制的上下文管理者。
Service Manager,它是整個Binder機制的守護進程,用來管理開發者創建的各種Server,並且向Client提供查詢Server遠程接口的功能
既然Service Manager組件是用來管理Server並且向Client提供查詢Server遠程接口的功能,那么,Service Manager就必然要和Server以及Client進行通信了。我們知道,Service Manger、Client和Server三者分別是運行在獨立的進程當中,這樣它們之間的通信也屬於進程間通信了,而且也是采用Binder機制進行進程間通信,因此,Service Manager在充當Binder機制的守護進程的角色的同時,也在充當Server的角色,然而,它是一種特殊的Server,下面我們將會看到它的特殊之處
Service Manager在用戶空間的源代碼位於frameworks/base/cmds/servicemanager目錄下,主要是由binder.h、binder.c和service_manager.c三個文件組成。Service Manager的入口位於service_manager.c文件中的main函數:
int main(int argc, char **argv) { struct binder_state *bs; void *svcmgr = BINDER_SERVICE_MANAGER; bs = binder_open(128*1024); if (binder_become_context_manager(bs)) { LOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler); return 0; }
main函數主要有三個功能:一是打開Binder設備文件;二是告訴Binder驅動程序自己是Binder上下文管理者,即我們前面所說的守護進程;三是進入一個無窮循環,充當Server的角色,等待Client的請求
2. Server和Client是如何獲得Service Manager接口的?即defaultServiceManager接口是如何實現的。
ServiceManager 作為守護進程,Service Manager的職責當然就是為Server和Client服務了。那么,Server和Client如何獲得Service Manager接口,進而享受它提供的服務呢?
Service Manager在Binder機制中既充當守護進程的角色,同時它也充當着Server角色,然而它又與一般的Server不一樣。對於普通的Server來說,Client如果想要獲得Server的遠程接口,那么必須通過Service Manager遠程接口提供的getService接口來獲得,這本身就是一個使用Binder機制來進行進程間通信的過程。而對於Service Manager這個Server來說,Client如果想要獲得Service Manager遠程接口,卻不必通過進程間通信機制來獲得,因為Service Manager遠程接口是一個特殊的Binder引用,它的引用句柄一定是0。
經過一系列的調用...
回到defaultServiceManager函數中,最終結果為:
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
這樣,Service Manager遠程接口就創建完成了,它本質上是一個BpServiceManager,包含了一個句柄值為0的Binder引用。
在Android系統的Binder機制中,Server和Client拿到這個Service Manager遠程接口之后怎么用呢?
對Server來說,就是調用IServiceManager::addService這個接口來和Binder驅動程序交互了,即調用BpServiceManager::addService 。而BpServiceManager::addService又會調用通過其基類BpRefBase的成員函數remote獲得原先創建的BpBinder實例,接着調用BpBinder::transact成員函數。在BpBinder::transact函數中,又會調用IPCThreadState::transact成員函數,這里就是最終與Binder驅動程序交互的地方了。回憶一下前面的類圖,IPCThreadState有一個PorcessState類型的成中變量mProcess,而mProcess有一個成員變量mDriverFD,它是設備文件/dev/binder的打開文件描述符,因此,IPCThreadState就相當於間接在擁有了設備文件/dev/binder的打開文件描述符,於是,便可以與Binder驅動程序交互了。
對Client來說,就是調用IServiceManager::getService這個接口來和Binder驅動程序交互了。具體過程上述Server使用Service Manager的方法是一樣的,這里就不再累述了。