概述
由于Android是基于Linux內(nèi)核的操作系統(tǒng)局劲,所以在了解Binder級(jí)之前需要先了解一些關(guān)于Linux的知識(shí),進(jìn)程隔離以及虛擬地址:
進(jìn)程隔離
進(jìn)程隔離是為保護(hù)操作系統(tǒng)中進(jìn)程互不干擾而設(shè)計(jì)的一組不同硬件和軟件的技術(shù)。這個(gè)技術(shù)是為了避免進(jìn)程A寫(xiě)入進(jìn)程B的情況發(fā)生刨啸。 進(jìn)程的隔離實(shí)現(xiàn),使用了虛擬地址空間。
虛擬地址
虛擬地址是對(duì)整個(gè)內(nèi)存的抽像描述羽圃。它是相對(duì)于物理內(nèi)存來(lái)講的,可以直接理解成“不真實(shí)的”抖剿,“假的”內(nèi)存朽寞,例如识窿,一個(gè)0x08000000內(nèi)存地址,它并不對(duì)就物理地址上那個(gè)大數(shù)組中0x08000000 - 1那個(gè)地址元素脑融;之所以是這樣喻频,是因?yàn)楝F(xiàn)代操作系統(tǒng)都提供了一種內(nèi)存管理的抽像,即虛擬內(nèi)存(virtual memory)肘迎。進(jìn)程使用虛擬內(nèi)存中的地址甥温,由操作系統(tǒng)協(xié)助相關(guān)硬件,把它“轉(zhuǎn)換”成真正的物理地址妓布。
正文
由于Linux的進(jìn)程隔離姻蚓,所以導(dǎo)致了進(jìn)程間不能直接進(jìn)行通信,那么Linux有沒(méi)有其它的通信方式呢秋茫,如果有的話史简,為什么要使用Binder作為IPC的通信方式?帶著這些疑問(wèn)肛著,來(lái)對(duì)Binder機(jī)制進(jìn)行一步一步的分析圆兵。
IPC原理
Client進(jìn)程向Server進(jìn)程通信,是利用進(jìn)程間可共享的內(nèi)核內(nèi)存空間來(lái)完成底層通信工作的枢贿,Client端與Server端進(jìn)程往往采用ioctl等方法跟內(nèi)核空間的驅(qū)動(dòng)進(jìn)行交互殉农。
IPC種類(lèi)
- 1.管道(Pipe):管道可用于具有親緣關(guān)系進(jìn)程間的通信,有名管道克服了管道沒(méi)有名字的限制局荚,因此超凳,除具有管道所具有的功能外,它還允許無(wú)親緣關(guān)系進(jìn)程間的通信耀态;
- 2.信號(hào)(Signal):信號(hào)是比較復(fù)雜的通信方式轮傍,用于通知接受進(jìn)程有某種事件發(fā)生,除了用于進(jìn)程間通信外首装,進(jìn)程還可以發(fā)送信號(hào)給進(jìn)程本身
- 3.(Message)隊(duì)列(消息隊(duì)列):消息隊(duì)列是消息的鏈接表创夜,包括Posix消息隊(duì)- 列system V消息隊(duì)列。有足夠權(quán)限的進(jìn)程可以向隊(duì)列中添加消息仙逻,被賦予讀權(quán)限的進(jìn)程則可以讀走隊(duì)列中的消息驰吓。消息隊(duì)列克服了信號(hào)承載信息量少,管道只能承載無(wú)格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)系奉。
- 4.共享內(nèi)存:使得多個(gè)進(jìn)程可以訪問(wèn)同一塊內(nèi)存空間檬贰,是最快的可用IPC形式。是針對(duì)其他通信機(jī)制運(yùn)行效率較低而設(shè)計(jì)的缺亮。往往與其它通信機(jī)制翁涤,如信號(hào)量結(jié)合使用,來(lái)達(dá)到進(jìn)程間的同步及互斥。
- 5.套接字(Socket):更為一般的進(jìn)程間通信機(jī)制迷雪,可用于不同機(jī)器之間的進(jìn)程間通信限书。
Binder原理
雖然虫蝶,Linux進(jìn)程間通信有很多種方式章咧,但是Android并沒(méi)有采用以上幾種,而是使用了Binder機(jī)制能真,在分析原因前赁严,還是先看看什么是Binder機(jī)制以及Binder機(jī)制的特點(diǎn):
- 1.直觀來(lái)說(shuō),Binder是Android中的一個(gè)類(lèi)粉铐,它繼承了IBinder接口
- 2.從IPC角度來(lái)說(shuō)疼约,Binder是Android中的一種跨進(jìn)程通信方式,Binder還可以理解為一種虛擬的物理設(shè)備蝙泼,它的設(shè)備驅(qū)動(dòng)是/dev/binder程剥,該通信方式在linux中沒(méi)有
- 3.從Android Framework角度來(lái)說(shuō),Binder是ServiceManager連接各種Manager(ActivityManager汤踏、WindowManager织鲸,etc)和相應(yīng)ManagerService的橋梁
- 4.從Android應(yīng)用層來(lái)說(shuō),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從字面意思來(lái)看是黏合劑,黏結(jié)劑的意思才避,那么它的作用必然是把什么東西連接在一起呢橱夭,在Android系統(tǒng)的Binder機(jī)制中,由一系統(tǒng)組件組成桑逝,分別是Client棘劣、Server、Service Manager和Binder驅(qū)動(dòng)程序肢娘,其中Client呈础、Server和Service Manager運(yùn)行在用戶空間,Binder驅(qū)動(dòng)程序運(yùn)行內(nèi)核空間橱健。Binder就是一種把這四個(gè)組件粘合在一起的粘結(jié)劑了而钞,其中,核心組件便是Binder驅(qū)動(dòng)程序了拘荡,Service Manager提供了輔助管理的功能臼节,Client和Server正是在Binder驅(qū)動(dòng)和Service Manager提供的基礎(chǔ)設(shè)施上,進(jìn)行Client-Server之間的通信。Service Manager和Binder驅(qū)動(dòng)已經(jīng)在Android平臺(tái)中實(shí)現(xiàn)好网缝,開(kāi)發(fā)者只要按照規(guī)范實(shí)現(xiàn)自己的Client和Server組件就可以了巨税。
Binder架構(gòu)
- Java應(yīng)用層: 對(duì)于上層應(yīng)用通過(guò)調(diào)用AMP.startService, 完全可以不用關(guān)心底層,經(jīng)過(guò)層層調(diào)用,最終必然會(huì)調(diào)用到AMS.startService.
- Java IPC層: Binder通信是采用C/S架構(gòu), Android系統(tǒng)的基礎(chǔ)架構(gòu)便已設(shè)計(jì)好Binder在Java framework層的Binder客戶類(lèi)BinderProxy和服務(wù)類(lèi)Binder;
- Native IPC層: 對(duì)于Native層,如果需要直接使用Binder(比如media相關(guān)), 則可以直接使用BpBinder和BBinder(當(dāng)然這里還有JavaBBinder)即可, 對(duì)于上一層Java IPC的通信也是基于這個(gè)層面.
- Kernel物理層: 這里是Binder Driver, 前面3層都跑在用戶空間,對(duì)于用戶空間的內(nèi)存資源是不共享的,每個(gè)Android的進(jìn)程只能運(yùn)行在自己進(jìn)程所擁有的虛擬地址空間, 而內(nèi)核空間卻是可共享的. 真正通信的核心環(huán)節(jié)還是在Binder Driver.
Binder通信流程
- Server在ServiceManager中注冊(cè)。
-Client想要調(diào)用Server的getName方法粉臊,就需要先獲取Server對(duì)象草添, 但是SM不會(huì)把真正的Server對(duì)象返回給Client,而是把Server的一個(gè)代理對(duì)象返回給Client扼仲,也就是Proxy远寸。 - 然后,Client調(diào)用Proxy的getName方法屠凶,SM會(huì)幫他去調(diào)用Server的getName方法驰后,并把結(jié)果返回給Client。
IPC方式對(duì)比
雖然Android已經(jīng)有很多的IPC方式了矗愧,但是Android依然采用Binder來(lái)進(jìn)行線程間通信灶芝,主要是從性能和安全性以及穩(wěn)定性的角度來(lái)考慮的。
- 管道:在創(chuàng)建時(shí)分配一個(gè)page大小的內(nèi)存唉韭,緩存區(qū)大小比較有限夜涕;
- 消息隊(duì)列:信息復(fù)制兩次,額外的CPU消耗纽哥;不合適頻繁或信息量大的通信钠乏;
- 共享內(nèi)存:無(wú)須復(fù)制,共享緩沖區(qū)直接付附加到進(jìn)程虛擬地址空間春塌,速度快晓避;但進(jìn)程間的同步問(wèn)題操作系統(tǒng)無(wú)法實(shí)現(xiàn),必須各進(jìn)程利用同步工具解決只壳;
- 套接字:作為更通用的接口俏拱,傳輸效率低,主要用于不通機(jī)器或跨網(wǎng)絡(luò)的通信吼句;
- 信號(hào)量:常作為一種鎖機(jī)制锅必,防止某進(jìn)程正在訪問(wèn)共享資源時(shí),其他進(jìn)程也訪問(wèn)該資源惕艳。因此搞隐,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。
- 信號(hào): 不適用于信息交換远搪,更適用于進(jìn)程中斷控制劣纲,比如非法內(nèi)存訪問(wèn),殺死某個(gè)進(jìn)程等谁鳍;
Android之所以采用Binder機(jī)制來(lái)進(jìn)行通信癞季,主要是基于性能劫瞳,安全以及穩(wěn)定性來(lái)考慮,Binder基于 Client-Server通信模式绷柒,傳輸過(guò)程只需一次拷貝志于,為發(fā)送發(fā)添加UID/PID身份,既支持實(shí)名Binder也支持匿名Binder废睦,安全性高;
參考資料
http://gityuan.com/2015/10/31/binder-prepare/
https://segmentfault.com/a/1190000007997113