Binder(膠水,粘合劑 ) 是Android系統(tǒng)最重要的特性之一。是系統(tǒng)間各個組建的橋梁。Android系統(tǒng)的開放式很大程度上得益于這種極其方便的跨進(jìn)程通信機(jī)制
理解Binder對于理解整個Android系統(tǒng)有著重要的作用,Android系統(tǒng)的四大組件,AMS,PMS等系統(tǒng)服務(wù)無一不與Binder掛鉤??梢哉f無Binder不Android
Binder分為 Binder對象 和 Binder驅(qū)動。
Binder 驅(qū)動
在Android系統(tǒng)中,這個運行在內(nèi)核空間的,負(fù)責(zé)各個用戶進(jìn)程通過Binder通信的內(nèi)核模塊叫做Binder驅(qū)動。但是Binder并不是Linux內(nèi)核的一部分,它可以訪問內(nèi)核空間是因為Linux的動態(tài)可加載內(nèi)核模塊(Loadable Kernel Module,LKM)機(jī)制。模塊是具有獨立功能的程序,它可以被單獨編譯,但不能獨立運行。它在運行時被鏈接到內(nèi)核作為內(nèi)核的一部分在內(nèi)核空間運行。
Binder 對象
Binder對象是一個可以夸進(jìn)程引用的對象,它的實現(xiàn)位于一個進(jìn)程中,而它的引用卻遍布與系統(tǒng)的各個進(jìn)程之中。最誘人的是,這個引用和java引用一樣,既可以是強(qiáng)類型,也可以是弱類型,而且可以從一個進(jìn)程傳遞給其他進(jìn)程,讓大家都能訪問同一個Server,就像將一個對象或引用賦值給另一個引用一樣。分為本地對象和代理對象
- Binder 本地對像:AIDL接口實現(xiàn)端的對象
- Binder 代理對象: 它只是Binder本地對象的一個遠(yuǎn)程代理;對這個Binder代理對象的操作,會通過Binder驅(qū)動最終轉(zhuǎn)發(fā)到Binder本地對象上去完成
Binder驅(qū)動是主要的內(nèi)核模塊,而整個Binder對象就是通訊載體??梢宰杂傻耐ㄟ^Binder驅(qū)動穿梭任意進(jìn)程。所以客戶端或者服務(wù)器可以把數(shù)據(jù)放入Binder對象里,然后進(jìn)行調(diào)用和通訊。
Binder 從不同的角度,可以有不同的解釋:
- 是Android的一個類,即Binder.java,實現(xiàn)了IBinder接口,
- 從IPC角度說,是Android的一種跨進(jìn)程通信方式,這種方式在Linux中沒有
- 還可以理解為一種虛擬的物理設(shè)備,Binder驅(qū)動,設(shè)備驅(qū)動在/dev/binder,
- 從Android Framework角度來說,是ServiceManager連接各種Manager(ActivityManager,WindowManager等)和形影的ManagerService的橋梁
- 從Android應(yīng)用層來說,是客戶端和服務(wù)端進(jìn)行通信的媒介,當(dāng)bindService的時候,服務(wù)端會返回一個包含了服務(wù)端業(yè)務(wù)調(diào)用的Binder對象,通過這個Binder對象,客戶端就可以獲取服務(wù)器提供的服務(wù)或者數(shù)據(jù)了,這里的服務(wù)包括普通的服務(wù)和基于AIDL的服務(wù)
- 對于Server進(jìn)程來說,Binder指的是Binder本地對象。
- 對于Client來說,Binder指的是Binder代理對象,對于一個擁有Binder對象的使用者而言,它無須關(guān)心這是一個Binder代理對象還是Binder本地對象;對于代理對象的操作和對本地對象的操作對它來說沒有區(qū)別。
- 對于傳輸過程而言,Binder是可以進(jìn)行跨進(jìn)程傳遞的對象;Binder驅(qū)動會對具有跨進(jìn)程傳遞能力的對象做特殊處理:自動完成代理對象和本地對象的轉(zhuǎn)換。
Binder模糊了進(jìn)程邊界,淡化了進(jìn)程間通信過程,整個系統(tǒng)仿佛運行與同一個面向?qū)ο蟮某绦蛑校涡紊腂inder對象以及星羅棋布的引用仿佛粘是結(jié)整個應(yīng)用程序的膠水,這也是Binder在英文中的原意。
Binder的工作過程
Binder的框架采用C/S架構(gòu),包含四個角色: Server,Client,ServiceManager(SM)以及Binder驅(qū)動。其中Server,Client,SM 運行用戶空間,而Binder驅(qū)動運行在內(nèi)核空間。
例如 一個 Client進(jìn)程想要調(diào)用Server進(jìn)程中的object對象的一個add()方法。
- 首先Server進(jìn)程要向SM注冊;告訴自己是誰,自己有什么能力;例如 它叫zhangsan,它有一個object對象,可以執(zhí)行add 操作;于是SM建立了一張表:zhangsan這個名字對應(yīng)進(jìn)程Server;
- 然后Client向SM查詢:我需要聯(lián)系一個名字叫做zhangsan的Server 進(jìn)程里面的object對象;這時候關(guān)鍵來了:進(jìn)程之間通信的數(shù)據(jù)都會經(jīng)過運行在內(nèi)核空間里面的Binder驅(qū)動,Binder驅(qū)動在數(shù)據(jù)流過的時候做了一點手腳,它并不會給Client進(jìn)程返回一個真正的object對象,而是返回一個看起來跟object一模一樣的代理對象objectProxy,這個objectProxy也有一個add方法,但是這個add方法只是一個傀儡,并沒有Server進(jìn)程里面object對象的add方法那個能力,它唯一做的事情就是把參數(shù)包裝然后交給Binder驅(qū)動。但是Client進(jìn)程并不知道Binder驅(qū)動返回給它的對象動過手腳,畢竟偽裝的太像了,如假包換。Client開開心心地拿著objectProxy對象然后調(diào)用add方法;我們說過,這個add什么也不做,直接把參數(shù)做一些包裝然后直接轉(zhuǎn)發(fā)給Binder驅(qū)動。
- 最后Binder驅(qū)動收到這個消息,發(fā)現(xiàn)是這個objectProxy;一查表就明白了:我之前用objectProxy替換了object發(fā)送給Client了,它真正應(yīng)該要訪問的是object對象的add方法;于是Binder驅(qū)動通知Server進(jìn)程,調(diào)用你的object對象的add方法,然后把結(jié)果發(fā)給我,Sever進(jìn)程收到這個消息,照做之后將結(jié)果返回Binder驅(qū)動,Binder驅(qū)動然后把結(jié)果返回給Client進(jìn)程;于是整個過程就完成了。
由于Binder驅(qū)動返回的objectProxy與Server進(jìn)程里面原始的object是如此相似,給人感覺好像是直接把Server進(jìn)程里面的對象object傳遞到了Client進(jìn)程;而實際上Client進(jìn)程只不過是持有了Server端的代理對象而已;代理對象協(xié)助驅(qū)動完成了跨進(jìn)程通信。因此,我們可以說Binder對象是可以進(jìn)行跨進(jìn)程傳遞的對象
Binder使用場景
Android開發(fā)中,Binder主要用于在Service中,包括AIDL和Messager,其中普通服務(wù)中的Binder不涉及到進(jìn)程通信,另外,ContentProvider底層實現(xiàn)也是Binder,
所以Binder的使用場景如下:
參考鏈接:
Android 開發(fā)藝術(shù)探索