Binder 學習http://blog.csdn.net/ylyuanlu/article/details/6629332java
Binder 的應用模型c++
一個IPC通信咱們能夠簡單的理解成客戶端-服務器模式,客戶端請求服務,服務端接收到客戶端請求後處理相應的請求,或可能帶回結果返回給客戶端。Binder機制在Android系統的進程間通信模型總結以下:編程
1)客戶端經過某種方式獲得服務器端的代理對象。從客戶端角度看來代理對象和他的本地對象沒有什麼差異。他能夠像其餘本地對象同樣調用其方法,訪問其變量。數組
2)客戶端經過調用代理對象的方法向服務器端發送請求信息。服務器
3)代理對象經過binder設備節點(/dev/binder),把用戶請求信息發送到Linux內核空間(實際上市內存共享),由binder驅動獲取併發送到服務進程。併發
4)服務器進程處理用戶請求,並經過Linux內核的binder驅動返回處理結果給客戶端的代理對象。框架
5)客戶端收到服務端的返回結果。函數
整個過程大體如上所述,能夠想象一下binder機制的引入,給進程間的通信帶來什麼好處?沒錯就是線程遷移,就像是一個線程帶着參數,進入另外一個進程執行,而後帶着結果返回,和調用本身的函數同樣的效果。oop
Binder機制的組成學習
1)binder驅動:binder是內核中的一個字符驅動設備位於/dev/binder。這個設備是Android系統IPC的核心部分,客戶端的代理服務來經過它想服務器(server)發送請求,服務器也是經過它把處理結果返回給客戶端的服務代理。這部份內容,在Android中經過一個IPCThreadState對象封裝了對Binder驅動的操做。
2)Service Manager:這個東西主要用來負責管理服務。Android中提供的系統服務都要經過Service Manager註冊本身,將本身添加進服務管理鏈表中,爲客戶提供服務服務。而客戶端若是要和特定的系統服務端通信,就要向Service Manager來查詢和得到所須要服務。能夠看出Service Manager是系統服務對象的管理中心。
3)服務(Server):須要強調的是這裏服務是指的是System Server,而不是SDK Server,向客戶端提供服務。
4)客戶端:通常是指Android系統上面的應用程序。它能夠請求Server中的服務。
5)代理對象:是指在客戶端應用程序中獲取生成的Server代理(proxy)類對象。從應用程序角度看代理對象和本地對象沒有差異,均可以調用其方法,方法都是同步的,而且返回相應的結果。
Binder機制的實現使用c c++實現的,但在Android的應用程序中,也會有java部分的內容。
Binder 之Service Manager
Service Manager在Android binder機制中的地位是至關的重要,全部的Server(System Server)都要向他註冊,應用程序須要向其查詢相應的服務。
service_manager.c是Service Manager的入口
int main(int argc, char **argv)
{
struct binder_state *bs;
void *svcmgr = BINDER_SERVICE_MANAGER;
bs = binder_open(128*1024);//打開binder設備,而後將該文件映射到內存中,並返回這塊內存的首地址這樣咱們就能夠像操做內存同樣,來操做這個文件了。
if (binder_become_context_manager(bs)) {//這個函數就是調用binder的ioctl設置成服務大管家。
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);//Service Manager的核心-循環體,調用一個回調函數,處理不一樣的請求
return 0;
}
Binder 之 服務代理對象
服務代理對象的應用模型:
1)首先客戶端向Service Manager查找相應的Service
2)Android系統的binder機制將會爲客戶端進程建立一個Service代理
3)客戶端視角只有Service代理,他全部對Service的請求都發往Service代理,而後由Service代理把用戶請求轉發給Service自己
4)Service處理完成後,吧結果返回給Service代理,Service代理負責把結果返回給客戶端
在Android系統中的任何進程,要想使用binder機制,必需要建立一個ProcessState對象和IPCThreadState對象。
咱們知道一個客戶端進程可能有多個Service的服務,這樣就會建立多個Service代理(BPBinder對象),那麼這個進程就須要一個東東來管理這些服務代理。ProcessState就是這個東東,它的做用就是維護當前進程中的全部Service代理。
defaultServiceManager生成一個IserviceManager對象sm,即Service Manager的服務代理,進程就是經過這個代理對象sm和Service Manager通信的,提供給本進程的其餘服務器端或客戶端訪問Service Manager的接口。
Binder 的服務代理對象步驟:
1)建立ProcessState對象,用來管理本進程中獲取的服務代理對象(根據客戶端傳的值),每一個進程智能建立一個該對象。
2)獲取了Service Manager的服務代理對象,能夠經過這個對象和服務管家通信了
3)實例化一些服務,並經過Service Manager代理對象向服務管家添加這些服務
4)服務端準備好了,就進入循環狀態,接收來自客戶端的請求
IPCThreadState對象的做用:
1)維護當前進程中全部對/dev/binder的讀寫,就是說當前進程經過binder機制進行跨進程條用都是經過IPCThreadState對象完成的
2)IPCThreadState也能夠理解成/dev/binder設備的封裝,用戶能夠不直接經過ioctl來操做binder設備
3)這個對象裏確定有循環的從binder設備中拿信息,而後處理
4)若是是客戶端進程,則經過服務代理BpBinder對象,調用transact函數,該函數做用就是把客戶端的請求寫入binder設備另外一端的Service進程
5)做爲Service進程,當他完成初始化工做以後,他們須要進入循環狀態等待客戶端的請求,Service進程調用他的IPCThreadState對象的joinThreadPool方法,開始輪詢binder設備,等待客戶端請求的到來
Binder 客戶端
整個服務代理的獲取過程也是binder機制的核心內容,它涉及了客戶請求,請求的傳遞和處理,服務代理的生成和轉換(封裝)過程。當客戶端獲取到對應服務的代理後,就能夠經過這個服務代理和服務通信了。
Binder機制中的java層
咱們知道Android中的應用程序基本上都是java開發,對Android的框架了解的朋友都知道,java的本地實現都是經過jni層的接口來調用C/C++代碼的,這裏也不例外。在Android的binder機制中,java層面的binder機制的應用,你能夠簡單看做是底層binder機制的封裝。
1)ServiceManager類型和對象
咱們都知道做爲客戶端要想得到服務代理,首相要建立ServiceManager代理對象,查詢Service,而後建立並返回服務代理對象,再經過代理對象和Service通信。
查看源碼ServiceManager就是IServiceManager對象的一個代理,他就是客戶端代理對象的一個封裝,由於建立和訪問這個代理對象都是經過ServiceManager的getIServiceManager方法,咱們建立ServiceManager服務對象,是經過jni調用native代碼,就是java的本地接口,來和底層的C/C++實現掛鉤。建立一個服務代理對象BpBinder,在native層,BpBinder繼承IBinder接口,把native層的IBinder對象封裝成java層的IBinder對象。以後根據描述符,查找BpBinder對應的本地服務代理對象並轉換爲IserviceManager類型
Binder之編程模型
1)在service_manager.c的結構數組allowed中添加新的服務名稱
2)定義一個繼承IInterface接口的ImyService.h
Class ImyService:public IInterface
{
Public:
DECLARE_META_INTERFACE(MyService);//重要的地方就是,這個宏定義和下個宏
....虛函數
}
3)跟着在ImyService.h中定義本地實現類BnMyService,須要繼承BnInterface,間接繼承了IMyService和BBinder
Class BnMyService:public BnInterface<IMyService>
{
virtual status_t onTransact();
}
4)在IMyService.cpp中,定義接口代理類BpMyService,須要繼承BpInterface
Class BpMyService:public BpInterface<IMyService>
{
Public:
BpMyservice(const sp<IBinder>& impl)
:BpInterface<IMyService>(impl){}//這裏的impl就是個BpBinder對象,和binder扯上關係
....h文件中定義的虛函數實現
}
5)在IMyService.cpp加入宏定義IMPLEMENT_META_INTERFACE(MyService,」***」)//這個宏和上個宏,new一個BpMyService類,並傳個BpBinder進去。
6)在IMyService.cpp中實現BnMyService類的onTrasact()接收BpMyService的onTrasact經過IPCThreadState發過來的數據,
7)建立真正的本地接口實現類MyService類頭文件,繼承BnMyService,定義功能函數和初始化函數instantiate()
8)在本地實現類MyService.cpp的instatiate()中把這個服務註冊到ServiceManager服務管家
9)在服務的進程入口函數裏調用服務的instantiate;這以後服務端的binder就搭建完成了
10)客戶端獲取服務代理對象
客戶端進程想要和服務端通信,首先須要獲取ServiceManager的代理對象,而後查找服務,返回該服務代理對象的引用,此代理對象中包含一個指向查找的服務的handle句柄
11)客戶端調用服務端函數
客戶端進程調用MyService的接口函數,調用會傳遞給包含了服務對象handler的代理對象的BpBinder,寫入binder內核驅動,binder驅動知道數據傳遞到的對象,因而將數據傳遞給該進程;服務端進程從binder驅動中讀取數據,而後處理遠程調用,而後發送reply數據給binder驅動,binder驅動將reply傳遞給客戶端進程,客戶端進程從binder驅動中讀取數據並最終獲取到reply,從而完成進程通訊。