幾個(gè)概念
進(jìn)程隔離:Binder是為保護(hù)操作系統(tǒng)中進(jìn)程互不干擾而設(shè)計(jì)的一組不同硬件和軟件的技術(shù)。這個(gè)技術(shù)是為了避免進(jìn)程A寫入進(jìn)程B的情況發(fā)生愿汰。 進(jìn)程的隔離實(shí)現(xiàn),使用了虛擬地址空間乐纸。進(jìn)程A的虛擬地址和進(jìn)程B的虛擬地址不同衬廷,這樣就防止進(jìn)程A將數(shù)據(jù)信息寫入進(jìn)程B。
用戶空間/內(nèi)核空間: Linux Kernel是操作系統(tǒng)的核心汽绢,獨(dú)立于普通的應(yīng)用程序吗跋,可以訪問受保護(hù)的內(nèi)存空間,也有訪問底層硬件設(shè)備的所有權(quán)限宁昭。把Kernel和上層的應(yīng)用程序抽像的隔離開跌宛,分別稱之為Kernel Space和User Space。
系統(tǒng)調(diào)用/內(nèi)核態(tài)/用戶態(tài):用戶空間訪問內(nèi)核空間的唯一方式就是系統(tǒng)調(diào)用积仗;通過這個(gè)統(tǒng)一入口接口疆拘,所有的資源訪問都是在內(nèi)核的控制下執(zhí)行,以免導(dǎo)致對(duì)用戶程序?qū)ο到y(tǒng)資源的越權(quán)訪問寂曹,從而保障了系統(tǒng)的安全和穩(wěn)定哎迄。
內(nèi)核模塊/驅(qū)動(dòng):通過系統(tǒng)調(diào)用回右,用戶空間可以訪問內(nèi)核空間,那么如果一個(gè)用戶空間想與另外一個(gè)用戶空間進(jìn)行通信怎么辦呢漱挚?--進(jìn)程間通信
Linux進(jìn)程間的通信機(jī)制:管道翔烁、信號(hào)量、共享內(nèi)存棱烂、socket等
Binder驅(qū)動(dòng): 通過利用Linux的動(dòng)態(tài)可加載內(nèi)核模塊(Loadable Kernel Module租漂,LKM)機(jī)制,Android系統(tǒng)可以通過添加一個(gè)內(nèi)核模塊運(yùn)行在內(nèi)核空間颊糜,用戶進(jìn)程之間的通過這個(gè)模塊作為橋梁哩治,就可以完成通信了。
Android為什么使用Binder?
Android基于Linux內(nèi)涵衬鱼,Linux內(nèi)核擁有著非常多的跨進(jìn)程通信機(jī)制业筏,比如管道,System V鸟赫,Socket等蒜胖;為什么還需要單獨(dú)搞一個(gè)Binder出來呢?
性能:在移動(dòng)設(shè)備上抛蚤,廣泛地使用跨進(jìn)程通信肯定對(duì)通信機(jī)制本身提出了嚴(yán)格的要求台谢;Binder相對(duì)出傳統(tǒng)的Socket方式,更加高效岁经;
安全:傳統(tǒng)的進(jìn)程通信方式對(duì)于通信雙方的身份并沒有做出嚴(yán)格的驗(yàn)證朋沮,只有在上層協(xié)議上進(jìn)行架設(shè);比如Socket通信ip地址是客戶端手動(dòng)填入的缀壤,都可以進(jìn)行偽造樊拓;而Binder機(jī)制從協(xié)議本身就支持對(duì)通信雙方做身份校檢,因而大大提升了安全性塘慕。這個(gè)也是Android權(quán)限模型的基礎(chǔ).
Binder是如何工作的筋夏?
Client、Server和Service Manager實(shí)現(xiàn)在用戶空間中图呢,Binder驅(qū)動(dòng)程序?qū)崿F(xiàn)在內(nèi)核空間中
Binder驅(qū)動(dòng)程序和Service Manager在Android平臺(tái)中已經(jīng)實(shí)現(xiàn)条篷,開發(fā)者只需要在用戶空間實(shí)現(xiàn)自己的Client和Server
Binder驅(qū)動(dòng)程序提供設(shè)備文件/dev/binder與用戶空間交互,Client蛤织、Server和Service Manager通過open和ioctl文件操作函數(shù)與Binder驅(qū)動(dòng)程序進(jìn)行通信
Client和Server之間的進(jìn)程間通信通過Binder驅(qū)動(dòng)程序間接實(shí)現(xiàn)
Service Manager是一個(gè)守護(hù)進(jìn)程拥娄,用來管理Server,并向Client提供查詢Server接口的能力
ServiceManager就像個(gè)電話本
1瞳筏、SM建立(建立通信錄);首先有一個(gè)進(jìn)程向驅(qū)動(dòng)提出申請(qǐng)為SM牡昆;驅(qū)動(dòng)同意之后姚炕,SM進(jìn)程負(fù)責(zé)管理Service摊欠。
2、各個(gè)Server向SM注冊(cè)(完善通信錄)柱宦;每個(gè)Server端進(jìn)程啟動(dòng)之后些椒,向SM報(bào)告,我是A 要找我請(qǐng)返回13405895674掸刊;其他Server進(jìn)程依次如此免糕;這樣SM就建立了一張表,對(duì)應(yīng)著各個(gè)Server的名字和地址忧侧;就好比B與A見面了石窑,說存?zhèn)€我的號(hào)碼吧,以后找我撥打13405895674蚓炬;
3松逊、Client想要與Server通信,首先詢問SM肯夏;請(qǐng)告訴我如何聯(lián)系A(chǔ)经宏,SM收到后給他一個(gè)號(hào)碼13405895674;Client收到之后驯击,開心滴用這個(gè)號(hào)碼撥通了Server的電話烁兰,于是就開始通信了。
1徊都、首先沪斟,Server進(jìn)程要向SM注冊(cè);告訴自己是誰碟贾,自己有什么能力币喧;在這個(gè)場(chǎng)景就是Server告訴SM,它叫A袱耽,它有一個(gè)object對(duì)象,可以執(zhí)行add 操作朱巨;于是SM建立了一張表:A這個(gè)名字對(duì)應(yīng)進(jìn)程Server
2史翘、然后Client向SM查詢:我需要聯(lián)系一個(gè)名字叫做A的進(jìn)程里面的object對(duì)象冀续;這時(shí)候關(guān)鍵來了:進(jìn)程之間通信的數(shù)據(jù)都會(huì)經(jīng)過運(yùn)行在內(nèi)核空間里面的驅(qū)動(dòng)洪唐,驅(qū)動(dòng)在數(shù)據(jù)流過的時(shí)候做了一點(diǎn)手腳凭需,它并不會(huì)給Client進(jìn)程返回一個(gè)真正的object對(duì)象,而是返回一個(gè)看起來跟object一模一樣的代理對(duì)象objectProxy旗国,這個(gè)objectProxy也有一個(gè)add方法注整,但是這個(gè)add方法沒有Server進(jìn)程里面object對(duì)象的add方法那個(gè)能力能曾;objectProxy的add只是一個(gè)傀儡,它唯一做的事情就是把參數(shù)包裝然后交給驅(qū)動(dòng)肿轨。
3寿冕、驅(qū)動(dòng)收到消息,發(fā)現(xiàn)是這個(gè)objectProxy萝招;一查表就明白了:我之前用objectProxy替換了object發(fā)送給Client了蚂斤,它真正應(yīng)該要訪問的是object對(duì)象的add方法;于是Binder驅(qū)動(dòng)通知Server進(jìn)程槐沼,調(diào)用你的object對(duì)象的add方法曙蒸,然后把結(jié)果發(fā)給我,Sever進(jìn)程收到這個(gè)消息岗钩,照做之后將結(jié)果返回驅(qū)動(dòng)纽窟,驅(qū)動(dòng)然后把結(jié)果返回給Client進(jìn)程;于是整個(gè)過程就完成了兼吓。
4臂港、由于驅(qū)動(dòng)返回的objectProxy與Server進(jìn)程里面原始的object是如此相似,給人感覺好像是直接把Server進(jìn)程里面的對(duì)象object傳遞到了Client進(jìn)程视搏;因此审孽,我們可以說Binder對(duì)象是可以進(jìn)行跨進(jìn)程傳遞的對(duì)象
5、這里隱藏了SM這一部分驅(qū)動(dòng)進(jìn)行的操作浑娜;實(shí)際上佑力,由于SM與Server通常不在一個(gè)進(jìn)程,Server進(jìn)程向SM注冊(cè)的過程也是跨進(jìn)程通信筋遭,驅(qū)動(dòng)也會(huì)對(duì)這個(gè)過程進(jìn)行暗箱操作:SM中存在的Server端的對(duì)象實(shí)際上也是代理對(duì)象打颤,后面Client向SM查詢的時(shí)候,驅(qū)動(dòng)會(huì)給Client返回另外一個(gè)代理對(duì)象漓滔。Sever進(jìn)程的本地對(duì)象僅有一個(gè)编饺,其他進(jìn)程所擁有的全部都是它的代理。
Binder是什么?
前面講到為何要使用Binder响驴,Binder的架構(gòu)是什么樣子的以及Binder是如何通信的透且。那么Binder到底是個(gè)啥呢?
Binder的設(shè)計(jì)采用了面向?qū)ο蟮乃枷牖砝穑贐inder通信模型的四個(gè)角色里面:
1石蔗、通常意義下罕邀,Binder指的是一種通信機(jī)制;我們說AIDL使用Binder進(jìn)行通信养距,指的就是Binder這種IPC機(jī)制。
2日熬、對(duì)于Server進(jìn)程來說棍厌,Binder指的是Binder本地對(duì)象
3、對(duì)于Client來說竖席,Binder指的是Binder代理對(duì)象耘纱,它只是Binder本地對(duì)象的一個(gè)遠(yuǎn)程代理;對(duì)這個(gè)Binder代理對(duì)象的操作毕荐,會(huì)通過驅(qū)動(dòng)最終轉(zhuǎn)發(fā)到Binder本地對(duì)象上去完成束析;對(duì)于一個(gè)擁有Binder對(duì)象的使用者而言,它無須關(guān)心這是一個(gè)Binder代理對(duì)象還是Binder本地對(duì)象憎亚;對(duì)于代理對(duì)象的操作和對(duì)本地對(duì)象的操作對(duì)它來說沒有區(qū)別员寇。
4、對(duì)于傳輸過程而言第美,Binder是可以進(jìn)行跨進(jìn)程傳遞的對(duì)象蝶锋;Binder驅(qū)動(dòng)會(huì)對(duì)具有跨進(jìn)程傳遞能力的對(duì)象做特殊處理:自動(dòng)完成代理對(duì)象和本地對(duì)象的轉(zhuǎn)換。
面向?qū)ο笏枷氲囊雽⑦M(jìn)程間通信轉(zhuǎn)化為通過對(duì)某個(gè)Binder對(duì)象的引用調(diào)用該對(duì)象的方法什往,而其獨(dú)特之處在于Binder對(duì)象是一個(gè)可以跨進(jìn)程引用的對(duì)象扳缕,它的實(shí)體(本地對(duì)象)位于一個(gè)進(jìn)程中,而它的引用(代理對(duì)象)卻遍布于系統(tǒng)的各個(gè)進(jìn)程之中别威。
這個(gè)引用和java里引用一樣既可以是強(qiáng)類型躯舔,也可以是弱類型,而且可以從一個(gè)進(jìn)程傳給其它進(jìn)程省古,讓大家都能訪問同一Server粥庄,就象將一個(gè)對(duì)象或引用賦值給另一個(gè)引用一樣。Binder模糊了進(jìn)程邊界衫樊,淡化了進(jìn)程間通信過程飒赃,整個(gè)系統(tǒng)仿佛運(yùn)行于同一個(gè)面向?qū)ο蟮某绦蛑小?/p>
Java層的Binder
IBinder是一個(gè)接口,它代表了一種跨進(jìn)程傳輸?shù)哪芰瞥蓿恢灰獙?shí)現(xiàn)了這個(gè)接口载佳,就能將這個(gè)對(duì)象進(jìn)行跨進(jìn)程傳遞;這是驅(qū)動(dòng)底層支持的臀栈;在跨進(jìn)程數(shù)據(jù)流經(jīng)驅(qū)動(dòng)的時(shí)候蔫慧,驅(qū)動(dòng)會(huì)識(shí)別IBinder類型的數(shù)據(jù),從而自動(dòng)完成不同進(jìn)程Binder本地對(duì)象以及Binder代理對(duì)象的轉(zhuǎn)換权薯。
IInterface代表的就是遠(yuǎn)程server對(duì)象具有什么能力姑躲, 表示client與server端的調(diào)用契約睡扬。具體來說,就是aidl里面的接口黍析。
Java層的Binder類卖怜,代表的其實(shí)就是Binder本地對(duì)象。BinderProxy類是Binder類的一個(gè)內(nèi)部類阐枣,它代表遠(yuǎn)程進(jìn)程的Binder對(duì)象的本地代理棉钧;這兩個(gè)類都繼承自IBinder, 因而都具有跨進(jìn)程傳輸?shù)哪芰η鼻铮粚?shí)際上,在跨越進(jìn)程的時(shí)候,Binder驅(qū)動(dòng)會(huì)自動(dòng)完成這兩個(gè)對(duì)象的轉(zhuǎn)換代赁。
在使用AIDL的時(shí)候污筷,編譯工具會(huì)給我們生成一個(gè)Stub的靜態(tài)內(nèi)部類帘睦;這個(gè)類繼承了Binder, 說明它是一個(gè)Binder本地對(duì)象疾党,它實(shí)現(xiàn)了IInterface接口,表明它具有遠(yuǎn)程Server承諾給Client的能力俊戳;Stub是一個(gè)抽象類揖赴,具體的IInterface的相關(guān)實(shí)現(xiàn)需要我們手動(dòng)完成,這里使用了策略模式品抽。