Android IPC系列--Binder

簡(jiǎn)介

什么是Binder?Android系統(tǒng)中,每個(gè)應(yīng)用程序是由Activity,Service,Broadcast,ContentProvider中一個(gè)或多個(gè)組合而成,他們都有各自的進(jìn)程,而如果要在這之間傳遞數(shù)據(jù),就會(huì)涉及到進(jìn)程間的通信。Binder是Android中用來(lái)實(shí)現(xiàn)進(jìn)程間通信的手段。熟悉Linux系統(tǒng)的讀者對(duì)進(jìn)程間通信肯定不會(huì)陌生,Linux下的IPC機(jī)制有很多種,比如:傳統(tǒng)的管道(Pipe)、信號(hào)(Signal)、跟蹤(Trace)這些基礎(chǔ)版本,他們只能實(shí)現(xiàn)父子進(jìn)程或者兄弟進(jìn)程之間的通信,后來(lái)又新增了三種“系統(tǒng)”級(jí)的通信機(jī)制,即:報(bào)文隊(duì)列(Message)、共享內(nèi)存(Share Memory)、信號(hào)量(Semaphore);再后來(lái)BSD Unix又對(duì)這些進(jìn)行了拓展,我們眾所周知的Socket就此出現(xiàn)。說(shuō)了這么多,并沒有看到本文的主角Binder?Android不是基于Linux發(fā)展來(lái)的嗎?其實(shí),是因?yàn)榭紤]到移動(dòng)設(shè)備的性能和功耗內(nèi)存你等特性,Android上自己設(shè)計(jì)了一種新的IPC方式,這個(gè)方式就是Binder。

IPC流程

IPC結(jié)構(gòu)圖.png

從示意圖中我們可以看出,每個(gè)Android的進(jìn)程,都會(huì)分配有屬于自己的用戶空間,然后有一個(gè)屬于系統(tǒng)的內(nèi)核空間,默認(rèn)是1G大小,這個(gè)內(nèi)核空間的大小是可以通過(guò)參數(shù)配置進(jìn)行調(diào)整的,具體怎么調(diào)有興趣的可以自己Google了解一下。各個(gè)用戶空間中的數(shù)據(jù)是獨(dú)立的,相互間沒辦法直接互相訪問(wèn),內(nèi)核空間是共有的,每個(gè)進(jìn)程都可以通過(guò)ioctl等方法來(lái)進(jìn)行交互。

Binder原理

Binder流程.png
注冊(cè)服務(wù)

由圖可以看出,服務(wù)端和客戶端是通過(guò)Server Manager建立連接的,Server首先會(huì)向Server Manager注冊(cè)服務(wù),ServiceManager向Binder驅(qū)動(dòng)發(fā)送 BC_TRANSACTION 命令,Binder驅(qū)動(dòng)收到命令后向ServerManager的tudo隊(duì)列添加一條注冊(cè)服務(wù)的事務(wù)來(lái)創(chuàng)建服務(wù)端進(jìn)程binder_node并插入到binder_procs鏈表中,同事注冊(cè)服務(wù)的線程進(jìn)入等待狀態(tài)。事務(wù)處理完后Binder會(huì)發(fā)送BR_TRANSACTION命令,ServiceManager收到命令后叫向svcinfo列表添加已經(jīng)注冊(cè)的服務(wù)進(jìn)去,并將等待的線程喚醒,至此我們的服務(wù)端注冊(cè)成功。

獲取服務(wù)

獲取服務(wù)的過(guò)程可以看成是注冊(cè)過(guò)程的相反。首先ServiceManager向Binder驅(qū)動(dòng)發(fā)送BC_TRANSACTION 命令,同時(shí)獲取服務(wù)的線程進(jìn)入等待狀態(tài);Binder驅(qū)動(dòng)收到命令后向ServiceManger發(fā)送BC_TRANSACTION ,ServiceManager查詢已注冊(cè)服務(wù)列表,查詢到即喚醒等待線程。

開始通訊

首先客戶端通過(guò)ServiceManager獲取到服務(wù)端的BinderProxy代理對(duì)象,通過(guò)代理對(duì)象將參數(shù),方法表示傳給ServiceManger,客戶端線程進(jìn)入等待狀態(tài)。
ServerManger將用戶空間的請(qǐng)求數(shù)據(jù)復(fù)制到內(nèi)核空間,并向服務(wù)端插入一條執(zhí)行方法的事務(wù),事務(wù)執(zhí)行完后通知ServiceManger將執(zhí)行結(jié)果從內(nèi)核空間復(fù)制出來(lái)給到用戶空間,將客戶端線程喚醒,完成一次通訊。

Binder原理

上文已經(jīng)介紹了服務(wù)端與客戶端進(jìn)程的整個(gè)通信過(guò)程了,雖然已經(jīng)知道了整個(gè)過(guò)程,但是其中原理是什么我們還是一無(wú)所知的,所以這里我們來(lái)探索一下Binder跨進(jìn)程通信的原理。首先我們從上面可以了解到,整個(gè)過(guò)程設(shè)計(jì)到四個(gè)部分,分別是Client端、Server端、ServerManger端還有內(nèi)核驅(qū)動(dòng)。整體結(jié)構(gòu)圖大概如下:


Binder原理.png

首先,Server需要向ServerManager注冊(cè)服務(wù),“登記”一些個(gè)人信息(方法屬性什么的),ServerManager會(huì)記記錄這些信息在自己的表中,然后服務(wù)端需要使用服務(wù)的時(shí)候就向ServerManger查詢客戶端需要哪個(gè)對(duì)象,由于進(jìn)程隔離的存在,他們直接是不能直接進(jìn)行數(shù)據(jù)交換的,這個(gè)時(shí)候驅(qū)動(dòng)的作用就體現(xiàn)出來(lái)了??蛻舳私?jīng)過(guò)驅(qū)動(dòng)的手獲取到了他想要的對(duì)象,但是事實(shí)上這個(gè)對(duì)象并不是服務(wù)端的存在的那個(gè)對(duì)象,它只是一個(gè)“山寨”的代理對(duì)象,它擁有服務(wù)端對(duì)象一模一樣的“外觀”,它能“欺騙”客戶端,使客戶端以為這個(gè)它想要的對(duì)象,然后就將自己的數(shù)據(jù)一五一十地交給了這個(gè)代理對(duì)象去處理,代理對(duì)象因?yàn)槭恰吧秸钡?,自己并沒有那個(gè)能力去處理這些數(shù)據(jù),只能返回給驅(qū)動(dòng),驅(qū)動(dòng)根據(jù)服務(wù)表查詢到服務(wù)端真正的對(duì)象后將數(shù)據(jù)交給這個(gè)對(duì)象去處理,并要求它將處理結(jié)果返回,得到處理的結(jié)果后,驅(qū)動(dòng)再次將數(shù)據(jù)傳遞到客戶端,至此,這個(gè)驚天“騙局”就完成了。
從上面的分析可以看出,Binder的所謂的夸進(jìn)程傳輸數(shù)據(jù),并不是把一個(gè)對(duì)象傳輸?shù)搅硪粋€(gè)進(jìn)程,它只是傳輸了一個(gè)仿制品,僅有外觀而無(wú)具體功能,客戶端進(jìn)程通過(guò)服務(wù)端進(jìn)程的代理,在驅(qū)動(dòng)的協(xié)助下完成了跨進(jìn)程通信。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容