Android進(jìn)程通信Binder機(jī)制詳解

前言

Binder是android中一個(gè)很重要且很復(fù)雜的概念,它在系統(tǒng)的整體運(yùn)作中發(fā)揮著極其重要的作用纳账,它是Android中的一種跨進(jìn)程通信方式。

為什么Android內(nèi)核要使用Binder
Android中有大量的CS(Client-Server)應(yīng)用方式,這就要求Android內(nèi)部提供IPC方法震糖,而linux所支持的進(jìn)程通信方式有兩個(gè)問題:性能和安全性。

目前l(fā)inux支持的IPC包括傳統(tǒng)的管道趴腋,System V IPC(消息隊(duì)列/共享內(nèi)存/信號(hào)量)吊说,以及socket,但只有socket支持Client-Server的通信方式优炬,由于socket是一套通用的網(wǎng)絡(luò)通信方式颁井,其傳輸效率低下切有很大的開銷,比如socket的連接建立過程和中斷連接過程都是有一定開銷的蠢护。消息隊(duì)列和管道采用存儲(chǔ)-轉(zhuǎn)發(fā)方式雅宾,即數(shù)據(jù)先從發(fā)送方緩存區(qū)拷貝到內(nèi)核開辟的緩存區(qū)中,然后再從內(nèi)核緩存區(qū)拷貝到接收方緩存區(qū)葵硕,至少有兩次拷貝過程眉抬。共享內(nèi)存雖然無需拷貝,但控制復(fù)雜懈凹,難以使用吐辙。
而Binder基于 Client-Server通信模式,傳輸過程只需一次拷貝蘸劈。

在安全性方面昏苏,傳統(tǒng)IPC沒有任何安全措施,完全依賴上層協(xié)議來確保。而Android為每個(gè)安裝好的應(yīng)用程序分配了自己的UID贤惯,可靠的身份標(biāo)記只有由IPC機(jī)制本身在內(nèi)核中添加洼专。
基于以上原因,Android需要建立一套新的IPC機(jī)制來滿足系統(tǒng)對通信方式孵构,傳輸性能和安全性的要求屁商,這就是Binder。

Binder通信原理:

Binder基于 Client-Server通信模式颈墅,傳輸過程只需一次拷貝蜡镶,為發(fā)送發(fā)添加UID/PID身份,既支持實(shí)名Binder也支持匿名Binder恤筛,包含角色:Server端A官还、Client端B、Binder驅(qū)動(dòng)毒坛、內(nèi)核空間望伦、物理內(nèi)存、ServiceManager

Binder-CS模型.png

步驟 描述 說明
注冊服務(wù) 1煎殷、Server進(jìn)程向binder驅(qū)動(dòng)發(fā)起服務(wù)注冊請求屯伞。2、Binder驅(qū)動(dòng)將注冊請求轉(zhuǎn)發(fā)給ServerManager進(jìn)程豪直。3劣摇、ServerManager進(jìn)程添加該Server進(jìn)程 此時(shí)ServerManager進(jìn)程擁有了Server進(jìn)程的信息
獲取服務(wù) 1、Client向Binder發(fā)起獲取服務(wù)的請求傳遞要獲取的服務(wù)名稱弓乙。2末融、Binder驅(qū)動(dòng)將該請求轉(zhuǎn)發(fā)到ServerManager進(jìn)程。 3唆貌、ServerManager查找到Client需要的Server對應(yīng)的服務(wù)信息。4垢乙、通過Binder驅(qū)動(dòng)將上述服務(wù)信息返回給Client進(jìn)程 此時(shí)Clinet進(jìn)程與Server進(jìn)程已建立了連接

注冊服務(wù)過程:
第一步: service通過調(diào)用serviceManager中的addService方法锨咙,然后調(diào)用ServiceManagerNative類中的addservice(name)方法。
第二步: ServiceManagerNative會(huì)通過Binder發(fā)送一條SVG_MGR_ADD_SERVICE的指令追逮,然后通過svcmgr_handler()調(diào)用do_add_service()方法往svc_list中添加相應(yīng)的service

獲取服務(wù)過程:
第一步:client要請求服務(wù)酪刀,比如說在activity中調(diào)用context.getSystemService()方法,這個(gè)時(shí)候serviceManager就會(huì)使用getService(name)钮孵,然后就會(huì)調(diào)用到native層中的ServiceManagerNative類中的getService(name)方法骂倘。
第二步:ServiceManagerNative會(huì)通過Binder發(fā)送一條SVG_MGR_GET_SERVICE的指令,然后通過svcmgr_handler()調(diào)用do_find_service()方法去svc_list中查找到相關(guān)的service巴席。
第三步:查找到相應(yīng)的服務(wù)后就會(huì)通過Binder將服務(wù)傳給ServiceManagerNative历涝,然后傳給serviceManager,最后client就可以使用了。

ServiceManager也是一個(gè)單獨(dú)的進(jìn)程荧库,那Server堰塌、Client如何與ServiceManager進(jìn)行通信呢?
實(shí)際上Client分衫、Server场刑、ServiceManager之間都是依靠Binder通信,只是ServiceManager作為特殊的Binder(handle=0)提前放入了Binder驅(qū)動(dòng)里蚪战,當(dāng)Client牵现、Server想要獲取ServiceManager的Binder引用,只需要獲取handle=0的Binder即可邀桑。

Binder驅(qū)動(dòng)在物理內(nèi)存中開辟一塊固定大邢固邸(1M-8K)的物理內(nèi)存w,與內(nèi)核空間的虛擬地址x進(jìn)行映射得到
A的用戶空間的虛擬地址ax和物理內(nèi)存w進(jìn)行映射
此時(shí)內(nèi)核空間虛擬地址x和物理內(nèi)存w已經(jīng)進(jìn)行了映射概漱,物理內(nèi)存w和Server端A的用戶空間虛擬地址ax進(jìn)行了映射:也就是 內(nèi)核空間的虛擬地址x = 物理內(nèi)存w = Server端A的用戶空間虛擬地址ax
B發(fā)送請求:將數(shù)據(jù)按照binder協(xié)議進(jìn)行打包給到Binder驅(qū)動(dòng)丑慎,Binder驅(qū)動(dòng)調(diào)用coay_from_user()將數(shù)據(jù)拷貝到內(nèi)核空間的虛擬地址x
因步驟3中的三塊區(qū)域進(jìn)行了映射
Server端A就得到了Client端B發(fā)送的數(shù)據(jù)
通過內(nèi)存映射關(guān)系,只發(fā)生了一次拷貝

Binder通信模型.png

Activity跳轉(zhuǎn)時(shí)瓤摧,最多攜帶1M-8k(1兆減去8K)的數(shù)據(jù)量竿裂;真實(shí)數(shù)據(jù)大小為:1M內(nèi)存-兩頁的請求頭數(shù)據(jù)=1M-8K;

流程:
每個(gè)App進(jìn)程啟動(dòng)時(shí)會(huì)在內(nèi)核空間中映射一塊1M-8K的內(nèi)存
服務(wù)端A的服務(wù)注冊到ServiceManager中:服務(wù)注冊
客戶端B想要調(diào)用服務(wù)端A的服務(wù)照弥,就去請求ServiceManager
ServiceManager去讓服務(wù)端A實(shí)例化服務(wù):服務(wù)發(fā)現(xiàn)
返回一個(gè)用來發(fā)送數(shù)據(jù)的對象BpBinder給到客戶端B
客戶端B通過BpBinder發(fā)送數(shù)據(jù)到服務(wù)端A的內(nèi)核的映射區(qū)域(傳參時(shí)客戶端會(huì)傳一個(gè)reply序列化對象腻异,在底層會(huì)將這個(gè)地址一層一層往下傳,直至傳到回調(diào)客戶端):這里發(fā)生了一次通信copy_from_user:服務(wù)調(diào)用
服務(wù)端A通過BBBinder得到數(shù)據(jù)并處理數(shù)據(jù)
服務(wù)端喚醒客戶端等待的線程这揣;將返回結(jié)果寫入到客戶端發(fā)送請求時(shí)傳的一個(gè)reply容器地址中,調(diào)用onTransact返回悔常;
客戶端在onTransac中得到數(shù)據(jù);通信結(jié)束给赞;
ServiceManager維持了Binder這套通信框架机打;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市片迅,隨后出現(xiàn)的幾起案子残邀,更是在濱河造成了極大的恐慌,老刑警劉巖柑蛇,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芥挣,死亡現(xiàn)場離奇詭異,居然都是意外死亡耻台,警方通過查閱死者的電腦和手機(jī)空免,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盆耽,“玉大人蹋砚,你說我怎么就攤上這事扼菠。” “怎么了都弹?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵娇豫,是天一觀的道長。 經(jīng)常有香客問我畅厢,道長冯痢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任框杜,我火速辦了婚禮浦楣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咪辱。我一直安慰自己振劳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布油狂。 她就那樣靜靜地躺著历恐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪专筷。 梳的紋絲不亂的頭發(fā)上弱贼,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機(jī)與錄音磷蛹,去河邊找鬼吮旅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛味咳,可吹牛的內(nèi)容都是我干的庇勃。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼槽驶,長吁一口氣:“原來是場噩夢啊……” “哼责嚷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掂铐,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤罕拂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后堡纬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聂受,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒿秦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年烤镐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棍鳖。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炮叶,死狀恐怖碗旅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情镜悉,我是刑警寧澤祟辟,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站侣肄,受9級特大地震影響旧困,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稼锅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一吼具、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矩距,春花似錦拗盒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渡嚣。三九已至捞慌,卻和暖如春屏镊,著一層夾襖步出監(jiān)牢的瞬間院领,已是汗流浹背愉阎。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工屯断, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留解孙,地道東北人回还。 一個(gè)月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓拼窥,卻偏偏與公主長得像戏蔑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子鲁纠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容