Binder簡(jiǎn)概

1.什么是Binder?簡(jiǎn)單描述下它的工作過(guò)程和使用場(chǎng)景?

(一)Binder是Android中的一個(gè)類,它實(shí)現(xiàn)了IBinder接口。

(1)從IPC角度來(lái)說(shuō):Binder是Android中的一種跨進(jìn)程通信方式,該通信方式在Linux中沒(méi)有,是Android獨(dú)有;
(2)從Android Driver層:Binder還可以理解為一種虛擬的物理設(shè)備,它的設(shè)備驅(qū)動(dòng)是/dev/binder;
(3)從Android Native層:Binder是創(chuàng)建Service Manager以及BpBinder/BBinder模型,搭建與binder驅(qū)動(dòng)的橋梁;
(4)從Android Framework層:Binder是各種Manager(ActivityManager、WindowManager等)和相應(yīng)xxxManagerService的橋梁;
(5)從Android APP層:Binder是客戶端和服務(wù)端進(jìn)行通信的媒介,當(dāng)bindService的時(shí)候,服務(wù)端會(huì)返回一個(gè)包含了服務(wù)端業(yè)務(wù)調(diào)用
的 Binder對(duì)象,通過(guò)這個(gè)Binder對(duì)象,客戶端就可以獲取服務(wù)端提供的服務(wù)或者數(shù)據(jù),這里的服務(wù)包括普通服務(wù)和基于AIDL的服務(wù)。

(二)Binder工作過(guò)程
首先我們要理解我們說(shuō)的Binder分為Binder對(duì)象和Binder驅(qū)動(dòng),即Binder驅(qū)動(dòng) 就是主的
內(nèi)核模塊,而這個(gè)Binder對(duì)象是通訊的載體,可以自由的通過(guò)Binder驅(qū)動(dòng)自由穿梭任意
進(jìn)程。所以客戶端或者服務(wù)器就可以把數(shù)據(jù)放入Binder對(duì)象里,然后進(jìn)行調(diào)用和通訊
類似于胞吞胞吐吧。

Binder通信模型
回想一下日常生活中我們通信的過(guò)程:假設(shè)A和B要進(jìn)行通信,通信的媒介是打電話(A是Client,B是Server);A要給B打電話,必須知道B的號(hào)碼,這個(gè)號(hào)碼怎么獲取呢?通信錄.
先查閱通信錄,拿到B的號(hào)碼;才能進(jìn)行通信;否則,怎么知道應(yīng)該撥什么號(hào)碼?回想一下古老的電話機(jī),如果A要給B打電話,必須先連接通話中心,說(shuō)明給我接通B的電話;這時(shí)候通話中心幫他呼叫B;連接建立,就完成了通信。
另外,光有電話和通信錄是不可能完成通信的,沒(méi)有基站支持;信息根本無(wú)法傳達(dá)。
我們看到,一次電話通信的過(guò)程除了通信的雙方還有兩個(gè)隱藏角色:通信錄和基站。Binder通信機(jī)制也是一樣:兩個(gè)運(yùn)行在用戶空間的進(jìn)程要完成通信,必須借助內(nèi)核的幫助,這個(gè)運(yùn)行在內(nèi)核里面的程序叫做Binder驅(qū)動(dòng),它的功能類似于基站;通信錄呢,就是一個(gè)叫做ServiceManager的東西(簡(jiǎn)稱SMgr)
另外,光有電話和通信錄是不可能完成通信的,沒(méi)有基站支持;信息根本無(wú)法傳達(dá)。
我們看到,一次電話通信的過(guò)程除了通信的雙方還有兩個(gè)隱藏角色:通信錄和基站。Binder通信機(jī)制也是一樣:兩個(gè)運(yùn)行在用戶空間的進(jìn)程要完成通信,必須借助內(nèi)核的幫助,這個(gè)運(yùn)行在內(nèi)核里面的程序叫做Binder驅(qū)動(dòng),它的功能類似于基站;通信錄呢,就是一個(gè)叫做ServiceManager的東西(簡(jiǎn)稱SMgr)

整個(gè)通信步驟如下:
SM建立(建立通信錄);首先有一個(gè)進(jìn)程向驅(qū)動(dòng)提出申請(qǐng)為SM;驅(qū)動(dòng)同意之后,SM進(jìn)程負(fù)責(zé)管理Service(注意這里是Service而不是Server,因?yàn)槿绻ㄐ胚^(guò)程反過(guò)來(lái)的話,那么原來(lái)的客戶端Client也會(huì)成為服務(wù)端Server)不過(guò)這時(shí)候通信錄還是空的,一個(gè)號(hào)碼都沒(méi)有。
各個(gè)Server向SM注冊(cè)(完善通信錄);每個(gè)Server端進(jìn)程啟動(dòng)之后,向SM報(bào)告,我是zhangsan, 要找我請(qǐng)返回0x1234(這個(gè)地址沒(méi)有實(shí)際意義,類比);其他Server進(jìn)程依次如此;這樣SM就建立了一張表,對(duì)應(yīng)著各個(gè)Server的名字和地址;就好比B與A見(jiàn)面了,說(shuō)存?zhèn)€我的號(hào)碼吧,以后找我撥打10086;
Client想要與Server通信,首先詢問(wèn)SM;請(qǐng)告訴我如何聯(lián)系z(mì)hangsan,SM收到后給他一個(gè)號(hào)碼0x1234;Client收到之后,開(kāi)心滴用這個(gè)號(hào)碼撥通了Server的電話,于是就開(kāi)始通信了。

為何選擇Binder
Linux已經(jīng)擁有管道,system V IPC,socket等IPC手段,卻還要倚賴Binder來(lái)實(shí)現(xiàn)進(jìn)程間通信,說(shuō)明Binder具有無(wú)可比擬的優(yōu)勢(shì)。

傳輸性能好

Binder很重要的的優(yōu)點(diǎn)之一就是,復(fù)雜數(shù)據(jù)類型傳遞可以復(fù)用內(nèi)存。

  • socket:是一個(gè)通用接口,導(dǎo)致其傳輸效率低,開(kāi)銷大,主要用在跨網(wǎng)絡(luò)的進(jìn)程間通信和本機(jī)上進(jìn)程間的低速通信
  • 管道和消息隊(duì)列:因?yàn)椴捎么鎯?chǔ)轉(zhuǎn)發(fā)方式,所以至少需要拷貝2次數(shù)據(jù),效率低;
  • 共享內(nèi)存:雖然在傳輸時(shí)沒(méi)有拷貝數(shù)據(jù),但其控制機(jī)制復(fù)雜。
  • Binder只需要拷貝內(nèi)存1次,而管道、消息隊(duì)列、Socket都需要對(duì)數(shù)據(jù)拷貝2次。

安全性高

傳統(tǒng)IPC沒(méi)有任何安全措施,完全依賴上層協(xié)議來(lái)確保。首先傳統(tǒng)IPC的接收方無(wú)法獲得對(duì)方進(jìn)程可靠的UID/PID(用戶ID/進(jìn)程ID),從而無(wú)法鑒別對(duì)方身份。
Android為每個(gè)安裝好的應(yīng)用程序分配了自己的UID,故進(jìn)程的UID是鑒別進(jìn)程身份的重要標(biāo)志。可靠的身份標(biāo)記只有由IPC機(jī)制本身在內(nèi)核中添加。
傳統(tǒng)IPC訪問(wèn)接入點(diǎn)是開(kāi)放的,無(wú)法建立私有通道。Binder可以使用匿名 Binder建立私密通道,別的進(jìn)程就無(wú)法通過(guò)窮舉或猜測(cè)等任何方式獲得該Binder的引用,向該Binder發(fā)送請(qǐng)求。

Binder使用的一些注意事項(xiàng)
Binder方法是在Binder線程池中被調(diào)用的,所以不需要再次new一個(gè)線程了,Client調(diào)用Server端方法,當(dāng)前線程會(huì)被調(diào)起,太耗時(shí)的話記得用一個(gè)線程來(lái)調(diào)用。
Intent攜帶的數(shù)據(jù)大小是限制了,不要超過(guò)1M,否則就會(huì)報(bào)一個(gè)TransactionTooLargeException的異常。這是因?yàn)锽inder數(shù)據(jù)的緩存大小就是1M。有的時(shí)候,即使一次攜帶的數(shù)據(jù)不到1M,還是可能會(huì)報(bào)異常,因?yàn)榇嬖诓l(fā)的情況。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容