用最通俗的語(yǔ)言總結(jié)Android Binder

角色: client 、 service 、 serviceManager 、Binder驅(qū)動(dòng)

場(chǎng)景: 前三出演在用戶空間,后者在內(nèi)核空間作為幕后

劇本: a. client帶著“絕密級(jí)文件”需要跟神秘的service進(jìn)行會(huì)晤

b. client只知道service名字,但不知其人

c. service壓根就不知道有client會(huì)找她

后臺(tái)策劃1: 如下圖


劇場(chǎng)開(kāi)幕: 基于以上劇本開(kāi)演,

a. 由于業(yè)務(wù)發(fā)展client需要開(kāi)展(調(diào)用)某項(xiàng)技能xx(方法)

b. 而這項(xiàng)技能掌握在server這種明星的手上

c. 由client(這種平民)直接要接觸到server,顯得太為不可能,那怎么拿到該項(xiàng)技能呢?

d. 代理,中間代理(就像租房中介)ta負(fù)責(zé)轉(zhuǎn)接“上與下(地位懸殊)”以及“租客與房東”此類關(guān)系的各種需求

e. proxy這里指的虛擬代理,真實(shí)代理還是binder負(fù)責(zé)

f. ?binder 在kernel 空間里為每一個(gè)進(jìn)程開(kāi)辟了一塊用來(lái)做“黑交易(數(shù)據(jù)交互)”的內(nèi)存區(qū)(存放client 與 server 進(jìn)程處理的數(shù)據(jù))

智能的binder 為了提高“交易效率與數(shù)量”實(shí)現(xiàn)了一套機(jī)制,不僅為每個(gè)進(jìn)程創(chuàng)建一塊內(nèi)存區(qū),

此外 還“專門(mén)開(kāi)辟了一塊共享內(nèi)存區(qū)用來(lái)存放處理完數(shù)據(jù)(以用來(lái)減少?gòu)膋ernel復(fù)制數(shù)據(jù)到用戶空間)” 見(jiàn)下面粉色(粉色粉色的)的圖

g. binder 對(duì)client來(lái)說(shuō), 將請(qǐng)求打包成binder特有格式“paracel”傳輸?shù)?server

binder 對(duì)server來(lái)說(shuō),將client給到的請(qǐng)求進(jìn)行處理后,把結(jié)果包裝到paracel 送到binder 進(jìn)行發(fā)貨

i. ?client 可以選擇兩種方式來(lái)等待server處理結(jié)果: 阻塞(同步)一直專心致的等啊等,非阻塞(異步)提出了要求后,就不管了(跑了去干啥啥了)

h. 以上是每一次client ?通過(guò) binder call method細(xì)節(jié)。

其實(shí)可總結(jié)為(“換做一種好理解的方式”),client通過(guò)binder 成功地獲取server對(duì)象實(shí)例的代理后,在本地任何操作就像是server親自發(fā)出指令一樣。

(這也是所謂的代理模式.... 姑且這么不恰當(dāng)理解&詮釋),不服的(不服的來(lái)打架啊.....)


后臺(tái)策劃2:


劇場(chǎng)開(kāi)演戲2: 基于策劃2開(kāi)演

導(dǎo)演不滿意,還要繼續(xù)BB.....

a. 例如client想要做一個(gè)“人生保健服務(wù)”但又不知道去哪里找店,于是打開(kāi)手機(jī)輸入字段“人生保健服務(wù)”,過(guò)了幾秒手機(jī)端就顯示了“周?chē)保ㄏ到y(tǒng)所具備的服務(wù))

b. 這里的ServicesManager將查詢結(jié)果(指向服務(wù)對(duì)象的類指針)返回給Client,

c. ?Client 拿到“地址”踹緊口袋立馬打了一個(gè)滴滴屁顛顛的去店里做保健(向服務(wù)端call method,以期等待得到特定數(shù)據(jù))

d. ?Client怎么找到服務(wù)的呢? 原因是server早已在ServiceManager里面注冊(cè)自己的門(mén)店,以等待顧客上門(mén)消費(fèi)

e. ?上面的一切都是在Binder地盤(pán)上完成交易,無(wú)奈他是老大,提供了交易平臺(tái)(否則,你以為隨隨便便就能找到保健店嗎,天真 ......)

劇終謝幕,采訪幕后者“Binder”

在以上交易完成后,請(qǐng)問(wèn)

a. ?如何做到做好對(duì)接client 與server 的數(shù)據(jù)交互(通信傳輸)?

b. ?在系統(tǒng)里面面對(duì)多個(gè)client 有請(qǐng)求數(shù)據(jù)時(shí),如何做到一一不落響應(yīng)每個(gè)客戶的請(qǐng)求?

c. ?binder掛掉了怎么辦?

以下統(tǒng)一回復(fù): ?謝謝 。

BpBinder對(duì)象:

a. ?客戶端通過(guò)它(IBinder)將數(shù)據(jù)請(qǐng)求傳達(dá)到Server端

BpBinder::transact(code ,Paracel&data,Paracel*reply, flags )

b. 緊接著IPCThreadState::transact(handle , code , Parcel &data , Paracel *reply , flags )收到命令立即將數(shù)據(jù)

裝入mOut變量里 (viawriteTransactionData(BC_TRANSACTION,flags , handle , code , data , NULL)

c. ?再通過(guò)waitForResponse(reply) ?把mOut的數(shù)據(jù)通過(guò)ioctl發(fā)送給 binder驅(qū)動(dòng) ?, 并得到 驅(qū)動(dòng)返回處理數(shù)據(jù). ? // 這里可設(shè)置等待方式(TF_ONE_WAY同步)

d. binder 只有一個(gè)文件描述符, ?系統(tǒng)里多客戶進(jìn)程同時(shí)執(zhí)行遠(yuǎn)程調(diào)用,并在ioctl上等待 處理結(jié)果, Android 如何保證其處理返回的數(shù)據(jù)能正確的交到正確的進(jìn)程呢?

這就是核心: "Android 在binder驅(qū)動(dòng)里記錄每次binder調(diào)用信息(包含線程ID),這樣根據(jù)ID可以知道將對(duì)應(yīng)的數(shù)據(jù)交給那個(gè)等待線程,喚醒該進(jìn)程來(lái)讀取緩沖區(qū)數(shù)據(jù)"

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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