說說Binder通信

是否理解binder可以說是android學習的一個分水嶺,因爲這個概念太重要了,對於我們理解一系列android先關其它知識都是特別重要的,比如我們要分析Activity以及Service組件啓動、ActivityManagerService以及WindowManagerService等系統服務,Binder通信都是繞不過去的一個重要知識點。這篇博客就來簡單的說說Binder的通信原理吧

1、Binder通信的組成部分

Binder方式通信有4大組成部分

部分 作用
Binder Client 發起Binder通信的一方
Binder Server 接收Binder Client的消息並據此給出迴應
ServiceManager 記錄Binder Server的Binder句柄,Client通過ServiceManager查詢目標Server的Binder句柄,並根據此Binder句柄同Server通信,同時ServiceManager本身也是一個Binder句柄爲0的特殊的Server
Binder Driver Binder驅動運行於內核態,實際上通過open("/dev/binder")來打開,其是Client和Server能通信的橋樑,Client發起的求情在Driver的binder_ioctl方法中顯示進行write操作寫數據,然後在read操作中進入休眠,等待Server寫入數據並激活Client讀數據,而Server則是先進行讀操作沒有數據就休眠等待Client寫數據激活Server處理數據

總的來說這4個部分的關係有點類似於IP通信中的Client Server Route以及DNS這4者之間的關係
在這裏插入圖片描述
其類比關係爲

Binder IP
Binder Client Client
Binder Server Server
ServiceManager DNS
Binder Driver Route

2、Binder Client向Binder Server發起通信的具體流程

Binder Client向Binder Server發起通信的具體流程可以通過下圖來說明
在這裏插入圖片描述
上圖實際上是Binder Client向ServiceManger發起通信的流程圖,前面說了ServiceManager實際上也是Binder Server,實際上我們通過這種特殊的通信流程能更容易的搞懂Binder通信原理。
感興趣的可以去跟以下代碼進行分析:

ServiceManager.getService("activity")

從上面流程圖可以看到一些關鍵點

BpBinder @BpBinder.cpp是native層封裝的IBinder對象,而BinderProxy @Binder.java則是java封裝的IBinder對象,兩者間通過JNI方式互相通信。實際上getService(“activity”)最終的目的也是爲了獲取一個帶AMS服務的Binder句柄來發起與AMS服務的Binder通信。

ProcessState @ProcessState.cpp對象在初始化是就負責初開打Binder Driver(open(/dev/binder))並且建立同Binder Driver之間的聯繫( ioctl )

IPCThreadState @IPCThreadState.cpp通過BpBinder->transact方法調用到它的IPCThreadState -> transact方法開始真正的與Binder Driver通信

另外,從流程圖也可以看出雖然BinderProxy、BpBinder、ProcessState以及IPCThreadState有些運行在java層,有些運行在native層,但是他們是運行在一個進程中的,共享進程資源。

通過以下時序圖能更清晰的看到他們之前調用關係:在這裏插入圖片描述這個時序圖可以看出顯示獲取handle爲0的BpBinder,實際上就是對應ServiceManager的BpBinder,然後通過這個BpBinder與ServiceManger進行Binder通信,最後獲取的是對應AMS句柄的BpBinder,從而與WMS進行Binder通信(這個步驟時序圖沒有體現)。

3、說說Client訪問AMS的過程

AMS的啓動時再systemserver進程中啓動的,它並不是獨享進程,其它服務比如WindowManagerService以及PowerManagerService都是在systemserver進程中啓動,和AMS是在通一進程中的,它們都是在Android系統開機的時候被首先啓動的。ServiceManager則不太一樣,它是在獨享server_manager進程。

AMS在systemserver中被啓動,同事被添加註冊到ServiceManager維護的服務列表中,並且開始循環監聽是否有客戶端向自己發送數據,如果當前沒有數據就進入休眠狀態,這一點原理上和ServiceManager是一樣的,雖然在具體的實現上有差異。

Binder Client向AMS發送bindeService命令,實際上最終也是通過BpBinder向Binder Driver寫數據並激活在休眠AMS線程,使得AMS開始處理數據,此時BinderClient進入休眠狀態等待AMS處理完數據後寫數據到Binder Driver然後激活處理休眠等待的Binder Client激活開始處理從AMS測傳過來的Parcel數據。從這個流程來看無論是Binder Client端還是Binder Server端,Binder通信都是阻塞的,所以對於Binder Client來說Binder通信不能放在主線程中進行避免發生ANR,實際上對應Android應用來說,啓動的時候就會自己爲當前進程創建兩個binder進程專門用來進行Binder通信。

這篇博客就此就算完結了,實際上對於新手來說看這篇博客意義不大,很多概念根本不知道是什麼,還是建議大家看看林學森寫的<深入理解Android內核設計思想> 第二版這本書吧,裏面關於Binder通信說的很詳細,相信能幫到大家更好的理解Binder通信的本質。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章