1.什么是Binder违孝?簡(jiǎn)單描述下它的工作過程和使用場(chǎng)景矿辽?
(一)Binder是Android中的一個(gè)類芭毙,它實(shí)現(xiàn)了IBinder接口嘱丢。
(1)從IPC角度來說:Binder是Android中的一種跨進(jìn)程通信方式,該通信方式在Linux中沒有,是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ì)象赫冬,通過這個(gè)Binder對(duì)象,客戶端就可以獲取服務(wù)端提供的服務(wù)或者數(shù)據(jù)溃列,這里的服務(wù)包括普通服務(wù)和基于AIDL的服務(wù)面殖。
(二)Binder工作過程
首先我們要理解我們說的Binder分為Binder對(duì)象和Binder驅(qū)動(dòng),即Binder驅(qū)動(dòng) 就是主的
內(nèi)核模塊哭廉,而這個(gè)Binder對(duì)象是通訊的載體,可以自由的通過Binder驅(qū)動(dòng)自由穿梭任意
進(jìn)程相叁。所以客戶端或者服務(wù)器就可以把數(shù)據(jù)放入Binder對(duì)象里遵绰,然后進(jìn)行調(diào)用和通訊
類似于胞吞胞吐吧辽幌。
Binder通信模型
回想一下日常生活中我們通信的過程:假設(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打電話,必須先連接通話中心彻采,說明給我接通B的電話腐缤;這時(shí)候通話中心幫他呼叫B;連接建立肛响,就完成了通信岭粤。
另外,光有電話和通信錄是不可能完成通信的特笋,沒有基站支持剃浇;信息根本無法傳達(dá)。
我們看到雹有,一次電話通信的過程除了通信的雙方還有兩個(gè)隱藏角色:通信錄和基站偿渡。Binder通信機(jī)制也是一樣:兩個(gè)運(yùn)行在用戶空間的進(jìn)程要完成通信,必須借助內(nèi)核的幫助霸奕,這個(gè)運(yùn)行在內(nèi)核里面的程序叫做Binder驅(qū)動(dòng)溜宽,它的功能類似于基站;通信錄呢质帅,就是一個(gè)叫做ServiceManager的東西(簡(jiǎn)稱SMgr)
另外适揉,光有電話和通信錄是不可能完成通信的,沒有基站支持煤惩;信息根本無法傳達(dá)嫉嘀。
我們看到,一次電話通信的過程除了通信的雙方還有兩個(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)槿绻ㄐ胚^程反過來的話驼仪,那么原來的客戶端Client也會(huì)成為服務(wù)端Server)不過這時(shí)候通信錄還是空的掸犬,一個(gè)號(hào)碼都沒有。
各個(gè)Server向SM注冊(cè)(完善通信錄)绪爸;每個(gè)Server端進(jìn)程啟動(dòng)之后湾碎,向SM報(bào)告,我是zhangsan, 要找我請(qǐng)返回0x1234(這個(gè)地址沒有實(shí)際意義毡泻,類比)胜茧;其他Server進(jìn)程依次如此;這樣SM就建立了一張表仇味,對(duì)應(yīng)著各個(gè)Server的名字和地址呻顽;就好比B與A見面了,說存?zhèn)€我的號(hào)碼吧丹墨,以后找我撥打10086廊遍;
Client想要與Server通信,首先詢問SM贩挣;請(qǐng)告訴我如何聯(lián)系z(mì)hangsan喉前,SM收到后給他一個(gè)號(hào)碼0x1234;Client收到之后王财,開心滴用這個(gè)號(hào)碼撥通了Server的電話卵迂,于是就開始通信了。
為何選擇Binder
Linux已經(jīng)擁有管道绒净,system V IPC见咒,socket等IPC手段,卻還要倚賴Binder來實(shí)現(xiàn)進(jìn)程間通信挂疆,說明Binder具有無可比擬的優(yōu)勢(shì)改览。
傳輸性能好
Binder很重要的的優(yōu)點(diǎn)之一就是,復(fù)雜數(shù)據(jù)類型傳遞可以復(fù)用內(nèi)存缤言。
- socket:是一個(gè)通用接口宝当,導(dǎo)致其傳輸效率低,開銷大胆萧,主要用在跨網(wǎng)絡(luò)的進(jìn)程間通信和本機(jī)上進(jìn)程間的低速通信
- 管道和消息隊(duì)列:因?yàn)椴捎么鎯?chǔ)轉(zhuǎn)發(fā)方式庆揩,所以至少需要拷貝2次數(shù)據(jù),效率低;
- 共享內(nèi)存:雖然在傳輸時(shí)沒有拷貝數(shù)據(jù)盾鳞,但其控制機(jī)制復(fù)雜犬性。
- Binder只需要拷貝內(nèi)存1次,而管道腾仅、消息隊(duì)列、Socket都需要對(duì)數(shù)據(jù)拷貝2次套利。
安全性高
傳統(tǒng)IPC沒有任何安全措施推励,完全依賴上層協(xié)議來確保。首先傳統(tǒng)IPC的接收方無法獲得對(duì)方進(jìn)程可靠的UID/PID(用戶ID/進(jìn)程ID)肉迫,從而無法鑒別對(duì)方身份验辞。
Android為每個(gè)安裝好的應(yīng)用程序分配了自己的UID,故進(jìn)程的UID是鑒別進(jìn)程身份的重要標(biāo)志喊衫〉欤可靠的身份標(biāo)記只有由IPC機(jī)制本身在內(nèi)核中添加。
傳統(tǒng)IPC訪問接入點(diǎn)是開放的族购,無法建立私有通道壳贪。Binder可以使用匿名 Binder建立私密通道,別的進(jìn)程就無法通過窮舉或猜測(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è)線程來調(diào)用只盹。
Intent攜帶的數(shù)據(jù)大小是限制了辣往,不要超過1M,否則就會(huì)報(bào)一個(gè)TransactionTooLargeException的異常殖卑。這是因?yàn)锽inder數(shù)據(jù)的緩存大小就是1M站削。有的時(shí)候,即使一次攜帶的數(shù)據(jù)不到1M懦鼠,還是可能會(huì)報(bào)異常钻哩,因?yàn)榇嬖诓l(fā)的情況。