詳細說說Binder通信原理與機制 [復制鏈接]

2019-8-28 10:11
xdingdang 閱讀:565 評論:0 贊:0
Tag:  Binder

先上一張Binder 的工作流程圖。(如果不清晰,可以 復制圖片鏈接到瀏覽器 或 保存到本地 查看,我經常都是這樣看圖的哈)

詳細說說Binder通信原理與機制

一開始上手,陌生的東西比較多,But,其實并不復雜。喔,流程圖是用 ProcessOn 畫的。很棒的在線畫圖工具。

出發前預備子彈 我們知道進程之間,虛擬地址不同,是不能直接通信的,這是一種保護機制。打開任務管理器,查看一下N多的進程,試想一下如果這些進程直接通信會帶來什么后果?

而用戶空間可以通過System calls(系統回調)與內核空間通信的,如果在內核空間中有一個模塊,能夠完成數據的轉發,那么是不是兩個進程就可以通信了呢?如下圖:

上面提到一些用戶空間、內核空間的概念,用戶空間也能大概猜到是什么東西,而內核空間,就知道它是很底層的東西好了。而模塊呢,可以簡單的理解為實現一個功能的程序或一個硬件電路等,比如玩單片機的時候,會有紅外線模塊,藍牙模塊,wifi模塊等。這些概念的東西搜索一下百科知道就好。

Binder驅動

Binder驅動運行在內核空間,它就是那個內核模塊了。Binder驅動很重要,承擔了進程間通信的數據轉發等。一提到驅動,也是比較熟悉,你插個U盤,需要驅動吧。而Binder驅動也差不多,雖然名字取得很好,功能還很強大。但也不是什么神奇的東西。

Binder跨進程通信模型

Binder的通信模型有4個角色:Binder Client、Binder Server、Binder Driver(Binder驅動)、ServiceManager。

想象一個情景:我到北京旅行,要給高中同學寄一張明信片,明信片肯定要寫上地址吧,不然怎么寄給對方呢?那么我怎么拿到這個地址呢,很簡單,翻一下畢業相冊就好了。而這個記錄著同學們通信地址的畢業相冊,就相當與一個通訊錄。在Binder的通信模型中扮演的是ServiceManager的角色。好,現在已經有了通信地址了,那么就找到郵局寄出去就好了。過幾天同學就高高興興的收到了明信片。那么這個郵局在Binder通信模型中扮演的是Binder驅動的角色,而作為寄信人的我就是Binder Client,收信人同學就是Binder Server。

先上一張圖來描述上面的那個情景:

詳細說說Binder通信原理與機制

可以看到,ServiceManager、Binder Client、Binder Server處于不同的進程,他們三個都在用戶空間,而Binder驅動在內核空間。(我是特意把Binder驅動畫的比較大的,因為Binder驅動的作用最大)

那先來簡述一下這個通信模型:

首先是有一個ServiceManager,剛開始這個通訊錄是空白的,然后Server進程向ServiceManager注冊一個映射關系表,比如徐同學把自己的地址廣東省廣州市xx區寫進通訊錄,那么就形成了一張表:

徐同學 —> 廣東省廣州市xx區

之后Client進程想要和Server進程通信,首先向ServiceManager查詢地址,ServiceManager收到查詢的請求之后,返回查詢結果給Client。

注意到這里不管是Server進程注冊,還是Client查詢,都是經過Binder驅動的,這也真是Binder驅動的作用所在,先不急,下面的原理會分析到。

這時候我就拿著地址就開始寄明信片咯。當我把明信片放扔進郵筒,之后的工作就是由郵局去完成了,也就是Binder驅動去完成通信的轉發。

Binder通信原理

從寄明信片的例子中,郵遞員從郵筒取出明信片,然后跨越千山萬水將明信片送達。從這點我們也能想到,其實Binder驅動完成的工作是很重要的。

我們來還原一個Binder跨進程通信的過程。 案例:Client進程調用Server進程的computer對象的add方法。

接下來的內容你可能需要知道代理模式才能更好的理解,不過沒學習過代理模式也沒關系,可以先讀下去,然后在去補一下代理模式,再回來看這篇文章。思路會清晰很多。

1. Server進程向ServiceManager注冊,告訴ServiceManager我是誰,我有什么,我能做什么。就好比徐同學(Server進程)有一臺筆記本(computer對象),這臺筆記本有個add方法。這時映射關系表就生成了。

2. Client進程向ServiceManager查詢,我要調用Server進程的computer對象的add方法,可以看到這個過程經過Binder驅動,這時候Binder驅動就開始發揮他的作用了。當向ServiceManager查詢完畢,是返回一個computer對象給Client進程嗎?其實不然,Binder驅動將computer對象轉換成了computerProxy對象,并轉發給了Client進程,因此,Client進程拿到的并不是真實的computer對象,而是一個代理對象,即computerProxy對象。很容易理解這個computerProxy對象也是有add方法,(如果連add方法都沒有,豈不是欺騙了Client?),但是這個add方法只是對參數進行一些包裝而已。

3. 當Client進程調用add方法,這個消息發送給Binder驅動,這時驅動發現,原來是computerProxy,那么Client進程應該是需要調用computer對象的add方法的,這時驅動通知Server進程,調用你的computer對象的add方法,將結果給我。然后Server進程就將計算結果發送給驅動,驅動再轉發給Client進程,這時Client進程還蒙在了鼓里,他以為自己調用的是真實的computer對象的add方法,其實他只是調用了代理而已。不過Client最終還是拿到了計算結果。

好了,一個通信過程就完成了。我們發現,其實Binder驅動就是一個中轉。

總結

再來梳理總結一下:當Client進程向ServiceManager查詢Server進程(我要調用你的某個對象的某個方法了),這個過程也是一個跨進程通信的過程,也經過了Binder驅動,這時Binder驅動發揮它的作用,來了個貍貓換太子,將Server進程中的真實對象轉換成代理對象,返回這個代理對象給Client進程。 Client進程拿到了這個代理對象,然后調用這個代理對象的方法,Binder驅動繼續發揮他的使命,它會通知Server進程執行計算工作,將Server進程中的真實對象執行的結果返回給了Client進程,這樣Client進程還是如愿的得到了自己想要。跨進程通信完畢


我來說兩句
您需要登錄后才可以評論 登錄 | 立即注冊
facelist
所有評論(0)
領先的中文移動開發者社區
18620764416
7*24全天服務
意見反饋:[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )

阿拉斯加垂钓APP下载
权威配资 体彩p3 十一运夺金 美国股票指数比中国股票指数高 即时比分 000427股票行情 欧冠足球直播 吉林快三 闪电配资 辽宁11选5 圣农发展股 竞彩比分danchang 甘肃十一选五 000157股票行情-和讯网 大盈家配资 黑龙江11选5