前言
Binder做為Android中核心機制,對於理解Android系統是必不可少的,關於binder的文章也有很多,但是每次看總感覺看的不是很懂,到底什麼才是binder機制?為什麼要使用binder機制?binder機制又是怎樣執行的呢?這些問題只是瞭解binder機制是不夠的,需要從Android的整體系統出發來分析,在我找了很多資料後,真正的弄懂了binder機制,相信看完這篇文章大家也可以弄懂binder機制。
1、Binder是什麼?
要理解binder,先要知道IPC,Inter-process communication ,也就是程式中相互通訊,Binder是Android提供的一套程式間相互通訊框架。用來多程式間傳送訊息,同步和共享記憶體。已有的程式間通訊方式有一下幾種:
1、Files 檔案系統(包括記憶體對映) 2、Sockets 3、Pipes 管道 4、共享記憶體 5、Intents, ContentProviders, Messenger 6、BinderAndroid系統中的Binder框架圖如下:
拿Activity舉例從上圖可以看出來:Activity是由ActivityManager來控制的,而ActivityManager其實是通過Binder獲取ActivityManagerService服務來控制Activity的,並且ActivityManager是Android系統FrameWork層的,和應用中的activity不是同一個程式。重點:
1、Binder是Android提供的一套程式間通訊框架。
2、系統服務ActivityManagerService,LocationManagerService,等都是在單獨程式中的,使用binder和應用進行通訊。
2、Android系統框架
如上圖,Android系統分成三層。最上層是application應用層,第二層是Framework層,第三層是native層。 由下圖可知幾點:1、Android中的應用層和系統服務層不在同一個程式,系統服務在單獨的程式中。
2、Android中不同應用屬於不同的程式中。
Android應用和系統services執行在不同程式中是為了安全,穩定,以及記憶體管理的原因,但是應用和系統服務需要通訊和分享資料。
優點
安全性:每個程式都單獨執行的,可以保證應用層對系統層的隔離。
穩定性:如果某個程式崩潰了不會導致其他程式崩潰。
記憶體分配:如果某個程式以及不需要了可以從記憶體中移除,並且回收相應的記憶體。
3、Binder通訊
client請求service服務,比如說Activity請求Activity ManagerService服務,由於Activity和ActivityManagerService是在兩個不同的程式中的,那麼下圖是一個很直觀的請求過程。
但是注意,一個程式是不能直接直接操作另一個程式的,比如說讀取另一個程式的資料,或者往另一個程式的記憶體空間寫資料,程式之間的通訊要通過核心程式才可以,因此這裡就要使用到程式通訊工具Binder瞭如下圖: Binder driver通過/dev/binder /dev/binder 提供了 open, release release, poll poll, mmap mmap, flush flush, and ioctl等操作的介面api。這樣程式A和程式B就可以通過核心程式進行通訊了。程式中大部分的通訊都是通過ioctl(binderFd, BINDER_WRITE_READ, &bwd)來進行的。bwd 的定義如下:struct binder_write_read {
signed long write_size;/* bytes to write */
signed long write_consumed; /* bytes consumed by driver */
unsigned long write_buffer;
signed long read_size; /* bytes to read */
signed long read_consumed; /* bytes consumed by driver */
unsigned long read_buffer;
};
複製程式碼
但是上面還有個問題就是client和service要直接和binder driver打交道,但是實際上client和service並不想知道binder相關協議,所以進一步client通過新增proxy代理,service通過新增stub來進一步處理與binder的互動。
這樣的好處是client和service都可以不用直接去和binder打交道。上面的圖好像已經很完善了,但是Android系統更進一步封裝,不讓client知道Binder的存在,Android系統提供了Manager來管理client。如下圖: 這樣client只需要交給manager來管理就好了,根本就不用關心程式通訊相關的事,關於manager其實是很熟悉的,比如說activity的就是由ActivityManager來控制的,ActivityManager是通過Binder獲取ActivityManagerService來控制activity的。這樣就不用我們自己來使用Binder來ActivityManagerService通訊了。更進一步,client是如何具體獲取到哪個service的呢?如下圖所示:
在service和binder之間還有一個contextManager,也就是serviceManager,每一個service要先往serviceManager裡面進行註冊,註冊完成之後由serviceManager統一管理。 在Android studio中可以通過adb指定列印出當前已經註冊過serviceManager的service。$ adb shell service list
Found 71 services: 0 sip:
[android.net.sip.ISipService] 1 phone: [com.android.internal.telephony.ITelephony] … 20 location: [android.location.ILocationManager] …
55 activity: [android.app.IActivityManager]
56 package: [android.content.pm.IPackageManager] …
67 SurfaceFlinger: [android.ui.ISurfaceComposer]
68 media.camera: [android.hardware.ICameraService]
69 media.player: [android.media.IMediaPlayerService]
70 media.audio_flinger: [android.media.IAudioFlinger]
複製程式碼
下圖是一次更加完整的client和service的通訊流程:
例項:應用呼叫location服務圖未完待續......