Android-IPC系列(二)

前言

寫完IPC的第一篇我就有點(diǎn)后悔了系宫。。因?yàn)閎inder的水太深了建车,老羅寫binder寫了十幾萬字。如果深入學(xué)習(xí)會大量涉及到系統(tǒng)層的知識腾降,甚至SM,Binder驅(qū)動(dòng)都是用c語言寫的犀盟。而晒。最近也是看了很多大牛關(guān)于binder的文章,可以說對binder的認(rèn)識又提升了一步且蓬。雖然我學(xué)的很淺欣硼,但是我盡量保證自己寫的都是對的! 來一波binder的最新認(rèn)識總結(jié)吧恶阴!~

Android_IPC系列(一)

上一篇文章主要是介紹一些簡單的linux知識,通過AIDL中的生成代碼來理解binder實(shí)現(xiàn)跨進(jìn)程的原理豹障。

任務(wù):

  1. 補(bǔ)充一些Linux知識冯事。
  2. binder實(shí)現(xiàn)跨進(jìn)程通信的實(shí)現(xiàn)流程是怎樣的
  3. 簡單介紹binder機(jī)制

一些補(bǔ)充知識

1.UserSpace, KernelSpace ,用戶態(tài),內(nèi)核態(tài)

用戶空間和內(nèi)核空間血公。內(nèi)核空間是linux系統(tǒng)的核心昵仅,可以訪問受保護(hù)資源和所有的硬件設(shè)備的權(quán)限。內(nèi)核獨(dú)立于應(yīng)用程序累魔,看起來是系統(tǒng)內(nèi)部的一個(gè)應(yīng)用摔笤。kernel有自己的保護(hù)措施,告知其他應(yīng)用程序他擁有什么權(quán)限垦写。所以在邏輯上吕世,將kernal和應(yīng)用程序抽離成兩塊空間。

當(dāng)某個(gè)應(yīng)用程序需要訪問內(nèi)核資源的時(shí)候梯投,可以通過系統(tǒng)調(diào)用來接入內(nèi)核命辖。然后內(nèi)核會來控制這個(gè)應(yīng)用程序?qū)Y源的訪問况毅,防止這個(gè)程序破壞系統(tǒng)資源,保證安全尔艇。這時(shí)候就會稱這個(gè)進(jìn)程處于內(nèi)核態(tài) 尔许。當(dāng)應(yīng)用程序在跑自己的代碼的時(shí)候,就稱為用戶態(tài)终娃。

2.Binder驅(qū)動(dòng)

Linux系統(tǒng)內(nèi)部是支持socket味廊,信號量等進(jìn)程通信的,但是安卓系統(tǒng)在性能和安全兩個(gè)方面設(shè)計(jì)了自己的進(jìn)程通信方式:Binder棠耕。兩個(gè)用戶空間想要通信余佛,必須通過內(nèi)核空間來支持。所以安卓就是將binder驅(qū)動(dòng)作為內(nèi)核模塊添加到Linux Kernel昧辽。Binder驅(qū)動(dòng)運(yùn)行在kernel空間衙熔,支持用戶空間的通信,可以堪稱一個(gè)橋梁搅荞,所有包含binder的數(shù)據(jù)包傳輸都會通過binder驅(qū)動(dòng)來完成红氯,無一例外!在binder驅(qū)動(dòng)里面咕痛,binder的實(shí)體和引用是以節(jié)點(diǎn)(struct)的形式存在的痢甘,包括server的binder實(shí)體,clinet里面擁有的binder引用茉贡,內(nèi)核的0號應(yīng)用以及SM的binder實(shí)體(后兩者后面會提到)塞栅。

驅(qū)動(dòng)是Binder通信的核心,系統(tǒng)中所有的Binder實(shí)體以及每個(gè)實(shí)體在各個(gè)進(jìn)程中的引用都登記在驅(qū)動(dòng)中腔丧;驅(qū)動(dòng)需要記錄Binder引用->實(shí)體之間多對一的關(guān)系放椰;為引用找到對應(yīng)的實(shí)體;在某個(gè)進(jìn)程中為實(shí)體創(chuàng)建或查找到對應(yīng)的引用愉粤;記錄Binder的歸屬地(位于哪個(gè)進(jìn)程中)砾医;通過管理Binder的強(qiáng)/弱引用創(chuàng)建/銷毀Binder實(shí)體等等。

3.ServiceManager, Binder,Clinet, Server

在Binder的機(jī)制中衣厘,SM, Clinet, Server以及上面提到的Binder驅(qū)動(dòng)是很重要的四個(gè)部分如蚜,而binder就可以看成是這四個(gè)部件之間溝通的管道。但是binder在每個(gè)部件里面的形態(tài)影暴,功能是完全不同的错邦。宏觀來看,binder可以看成是安卓跨進(jìn)程通信的方式型宙,工具撬呢,協(xié)議。微觀的來看早歇,binder可以看成各個(gè)部件里面重要的結(jié)構(gòu)倾芝,類讨勤,binder可以看成binder驅(qū)動(dòng)里面的紅黑樹數(shù)據(jù)結(jié)構(gòu),binder可以看成進(jìn)程之間傳輸?shù)臄?shù)據(jù)包晨另。binder作為膠水潭千,將不同的進(jìn)程粘合在一起,模糊了進(jìn)程隔離借尿。

ServiceManager是獨(dú)立于client, server的系統(tǒng)進(jìn)程刨晴。是由zygote進(jìn)程fork出來的。它在IPC通信中的作用是作為"通訊錄"路翻。所有的server里面的binder實(shí)體會先在SM里面注冊自己的信息狈癞,key是binder的名字(獨(dú)一無二),在AIDL的生成代碼里面你會看到這個(gè)玩意:

private static final java.lang.String DESCRIPTOR ="com.example.zane.ipc_test.IBookManager";

value就是這個(gè)binder的引用茂契,這樣就把這個(gè)binder的信息保存下來了蝶桶。也就是說client需要通過SM,以名字來去得到server的binder引用掉冶。然后通過這個(gè)引用去操作server端的binder真竖。這里也體現(xiàn)了binder中面向?qū)ο蟮脑O(shè)計(jì)理念。clinet自己并不知道自己獲得的這個(gè)binder引用是真的實(shí)體還是什么假的實(shí)體厌小,它只會去拿著自己獲得的引用去操作恢共。并且server中binder實(shí)體的引用會在SM,和所有需要跟自己通信的clinet里面存在。在這里璧亚,你可以把引用看成指針讨韭,或者代理對象。

client和server就是客戶端和服務(wù)端癣蟋。

在服務(wù)端:如果你熟悉AIDL進(jìn)行進(jìn)程間通信的流程或者看過我上篇博客透硝,你應(yīng)該對binder的存在形式有所體會。首先是一個(gè)aidl類型的接口疯搅,定義了binder的所有功能函數(shù)蹬铺。并且這些功能函數(shù)需要被編號,因?yàn)榉?wù)端是通過解析客戶端傳遞過來的數(shù)據(jù)包中的函數(shù)編號來知道自己應(yīng)該去調(diào)用什么函數(shù)秉撇。在Stub類中有這么幾行代碼(函數(shù)編號):

static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);

我們知道Stub就是Binder在Server的實(shí)體,里面實(shí)現(xiàn)了很多函數(shù)秋泄,onTransact()就是來分析客戶端的請求類型的函數(shù)琐馆,然后調(diào)用相應(yīng)的函數(shù),并且將返回結(jié)果放在數(shù)據(jù)包中返回給客戶端恒序。

在客戶端:同樣的瘦麸,我們在客戶端也需要去實(shí)現(xiàn)Binder,只不過這個(gè)binder是SM轉(zhuǎn)發(fā)給我們的歧胁,如果客戶端和服務(wù)端在同一個(gè)進(jìn)程滋饲,那么就會返回binder實(shí)體厉碟,如果不在同一個(gè)進(jìn)程就會返回binder的代理。由于binder代理和binder實(shí)體都是實(shí)現(xiàn)了AIDL接口的類屠缭。所以客戶端看不出來這個(gè)binder是實(shí)體或是引用箍鼓。如果你做過IPC通信,你會知道以上的過程是通過asInterface(IBiner binder)這個(gè)方法實(shí)現(xiàn)的呵曹。


實(shí)現(xiàn)流程

直接上一張我自己畫的簡介圖款咖!

簡介圖
簡介圖

可以很清楚的看出,binder驅(qū)動(dòng)是整個(gè)流程的核心奄喂!

1.Server將自己的binder通過binder驅(qū)動(dòng)在SM中進(jìn)行注冊铐殃。

2.binder驅(qū)動(dòng)會建立一個(gè)binder實(shí)體的數(shù)據(jù)節(jié)點(diǎn)和實(shí)體的引用。

3.Binder驅(qū)動(dòng)再把名字和引用打包發(fā)給SM跨新。

4.Client通過binder驅(qū)動(dòng)拿著他所需要的binder名字向SM請求binder富腊。

5.SM在自己的查找表里面找到對應(yīng)的引用之后再通過binder驅(qū)動(dòng)返回給client。

所有的系統(tǒng)服務(wù)在SystemServer進(jìn)程深沉之后就會被建立并且注冊在ServiceManager里面域帐,開發(fā)者也可以開發(fā)自定義的服務(wù)并且注冊在ServiceManager里面成為系統(tǒng)級別的服務(wù)赘被,前提是這個(gè)包含服務(wù)的應(yīng)用必須是system用戶并且?guī)Я藄ystem簽名(系統(tǒng)安全),否則是不能隨意注冊的俯树!

好了帘腹,再來一張我在一位大牛博客里面截下來的圖片,這個(gè)流程描述就更具體了:

ipc2-2.png

其實(shí)就是多了binder驅(qū)動(dòng)里面的一些數(shù)據(jù)結(jié)構(gòu)節(jié)點(diǎn)和一個(gè)叫0號引用的東西许饿。那么這個(gè)0號引用是什么呢阳欲?我們知道SM, Client, Server都是運(yùn)行在三個(gè)不同的進(jìn)程的。那么第一步Server要向SM注冊自己binder的信息陋率,那么這里已經(jīng)涉及到了跨進(jìn)程通信了球化。那么這個(gè)進(jìn)程通信是怎么實(shí)現(xiàn)的呢?通過上圖可以看到瓦糟,所有的Client里面的0號引用都指向了SM里面的binder筒愚。也就是說SM和其他所有Server通信的過程都是SM先通過特殊的命令在biner驅(qū)動(dòng)中建立了自己binder的實(shí)體節(jié)點(diǎn),并且其他所有地方的0號引用都默認(rèn)留給SM的binder實(shí)體引用菩浙。


結(jié)束語

上一篇文章講的AIDL生成代碼的分析巢掺,本來準(zhǔn)備第二篇總結(jié)一下AIDL的使用。后來通過不斷的學(xué)習(xí)覺得這篇文章講的東西更值得總結(jié)劲蜻!

總之陆淀,binder要學(xué)習(xí)的東西還是很多。比如binder協(xié)議先嬉,binder傳輸數(shù)據(jù)包類型轧苫,binder在驅(qū)動(dòng)里面的數(shù)據(jù)結(jié)構(gòu),緩存和線程池管理等等…Binder在安全性疫蔓,效率性都優(yōu)于Linux系統(tǒng)默認(rèn)支持的IPC通信方式,擁有面向?qū)ο蟮脑O(shè)計(jì)原理含懊。

未經(jīng)博主同意身冬,不得轉(zhuǎn)載該篇文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市岔乔,隨后出現(xiàn)的幾起案子酥筝,更是在濱河造成了極大的恐慌,老刑警劉巖重罪,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件樱哼,死亡現(xiàn)場離奇詭異,居然都是意外死亡剿配,警方通過查閱死者的電腦和手機(jī)搅幅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呼胚,“玉大人茄唐,你說我怎么就攤上這事∮” “怎么了沪编?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長年扩。 經(jīng)常有香客問我蚁廓,道長,這世上最難降的妖魔是什么厨幻? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任相嵌,我火速辦了婚禮,結(jié)果婚禮上况脆,老公的妹妹穿的比我還像新娘饭宾。我一直安慰自己,他們只是感情好格了,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布看铆。 她就那樣靜靜地躺著,像睡著了一般盛末。 火紅的嫁衣襯著肌膚如雪弹惦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天悄但,我揣著相機(jī)與錄音肤频,去河邊找鬼。 笑死算墨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的汁雷。 我是一名探鬼主播净嘀,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼报咳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挖藏?” 一聲冷哼從身側(cè)響起暑刃,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膜眠,沒想到半個(gè)月后岩臣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宵膨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年架谎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辟躏。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谷扣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捎琐,到底是詐尸還是另有隱情会涎,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布瑞凑,位于F島的核電站末秃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏籽御。R本人自食惡果不足惜练慕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望篱蝇。 院中可真熱鬧贺待,春花似錦、人聲如沸零截。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涧衙。三九已至哪工,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弧哎,已是汗流浹背雁比。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撤嫩,地道東北人偎捎。 一個(gè)月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親茴她。 傳聞我的和親對象是個(gè)殘疾皇子寻拂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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