圖解Android中的binder機制

Hanking發表於2020-04-05

前言

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、Binder

Android系統中的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服務圖

在這裡插入圖片描述

未完待續......

參考文獻

1、rts.lab.asu.edu/web_438/pro…

2、rts.lab.asu.edu/web_438/pro…

相關文章