Android特有Binder與IPC機制原理初探,看完應該理解一些些。
前言概述
Binder網上有很多文章要麼講的深入全是LInux核心指令C語言分析,要麼空洞無腦。這裡個人理解整理如下。
- 什麼是Binder:
1.Binder是一個類實現了IBinder介面,目的就是為了IPC服務而存在的。程序間通訊的必須依賴的東西。
2.Binder是ServiceManager連線各種Manager(ActivityManager、WindowManager…….)和相應的系統底層ManagerService的橋樑。
3.Binder本意就是一個驅動程式,提供裝置檔案在Framework/dev/binder。
- 什麼是IPC(Inter-Process Communication)
1.IPC是跨程序(由於Andoird每個APP都至少是擁有一個程序)也可理解跨應用間通訊,可以對比(Handler是執行緒間通訊的橋樑).
2.Android每個應用都單獨擁有一個Pid(程序ID),相互呼叫資料就需要IPC,但是Adroid OS 不允許我們直接像物件一樣呼叫方法獲取資料,所以我們需要Binder驅動IPC通訊。
3.Binder的IPC與一般IPC的區別
我們都知道且最常用的Socket也是IPC通訊,通用的網路通訊方式,但是建立Socket連線銷燬都有一定的開銷;訊息佇列和管道採用儲存-轉發方式,即資料先從傳送方快取區拷貝到核心開闢的快取區中,然後再從核心快取區拷貝到接收方快取區,資料傳遞至少有兩次拷貝過程,所以對於移動應用效率不行,考慮IPC之間的安全問題,以及Binder支援1對多,Android OS就使用自己的驅動Binder來服務IPC;
理解IPC需要關注的幾個點
ServiceManager
系統服務和我們自定義服務可以存放的地點,內部HashMap(String, IBinder)存放Binder,通過這個類我們可以獲取到系統提供的服務流程大概如此
為什麼通過Binder就能夠跨程序了呢?
首先我們的Android OS 程序資料共享圖
IOCTL就是使用者空間與核心互動資料的驅動函式。
通過這一點我們就肯定知道Binder是肯定能夠在核心空間與使用者空間之間傳遞資料才能夠實現我們需要IPC,下圖也就是我們Binder乾的事情;
這也使得我們實現Aidl來進行跨程序語言自定義型別的時候為什麼要序列化物件,才能夠實現IPC通訊,因為底層並不認識JAVA物件,需要parcelable序列化後,實現writeToParcel與readFromParcel,來實現IPC通訊。Parcel就是我們程序間資料儲存的一個容器。,把資料寫入到Parcel,Binder對其解析送到遠端服務端,由遠端服務端再次解析執行對應的函式,又通過Binder來返回到使用者程序.
怎麼使用系統服務呢?
//獲取WindowManager服務引用
WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE); //AudioService 》AudioManager
// NotificationManagerService》 NotificationManager
//
其實JAVA中這部分的服務大部分都有一個供使用者空間使用的manager類,這就是一個最正常的RPC呼叫,使用者通過呼叫xxxManager的方法,實際上被Binder給遷移到系統服務程序中對應的SystemManagerService中對應的方法,並將結果再通過binder帶回。
總結
本文只是對Binder機制的一些個人理解總結,並沒有深入研究,
可參考老羅blog,有時間自己還是要從原始碼去深入理解下。
如何在最新版AS2.2版本下使用Aidl建立自定義型別的遠端服務,見下篇Blog!