Android之Binder機制

1. 簡介

Binder,中文即粘合劑,意思是粘合了兩個不同的進程。從IPC角度來說,Binder是Android中的一種跨進程通信方式。

2. 基礎概念介紹

2.1 進程隔離&跨進程通信

  • 進程隔離:爲了保證安全性和獨立性,一般情況下,一個進程不能直接操作或訪問另外一個進程。即Android中的進程是相互隔離,獨立的
  • 進程通信:即IPC,不同進程需要進行數據的交互和通信

2.2 內核空間&用戶空間

  • 一個進程空間分爲內核空間和用戶空間,即內核空間和用戶空間相隔離
  • 內核空間:即Karnel Space,是Linux內核的運行空間。可以執行任何命令, 調用系統的一切資源。與用戶空間隔離,即使用戶的程序崩潰了,內核也不會受到影響。內核空間可進行進程間,進程內的交互。內核空間的數據是共享的,故內核空間=可共享空間
  • 用戶空間:即User Space,是用戶程序的運行空間。只能進行簡單的操作,在用戶空間的進程不能直接交互,可以通過內核空間來進行間接交互,但是又不能直接調用系統的資源,必須通過系統接口(System Call),向內核發出命令。用戶空間的數據不共享,給用戶空間=不可共享空間

2.3 內存映射

  • 定義:關聯一個虛擬內存區域和一個磁盤上的共享對象,使兩者存在映射關係
  • 實現過程:通過Linux系統調用函數:mmap(),這個函數的作用就是創建虛擬內存區域,並與共享對象建立映射關係
  • 特點:減少了數據拷貝的次數,並通過映射區域實現用戶空間和內核空間的交互

傳統跨進程通信需要拷貝數據兩次,Binder機制只需要1次,主要是因爲Binder機制使用到了內存映射

3. 四大角色

  • Client:使用服務的進程
  • Server:提供服務的進程
  • ServiceManager:管理系統的Server的註冊和查詢(將字符形式的Binder名字轉化成Client對該Binder的引用)
  • Binder驅動:虛擬設備驅動,連接Client,Server,ServiceManager的橋樑

3.1 Binder驅動

Binder驅動是Binder通信的核心,它工作於內核空間,提供open,mmap,ioctl等標準文件操作。驅動負責進程間Binder通信的建立。分別管理着Server端的Binder實體核Client端的引用。

4. Binder框架

  • Binder通信採用C/S模式,包括四個組件:Client,Server,ServiceManager,Binder驅動。其中Client,Server,ServiceManager運行在用戶空間,Binder驅動運行在內核空間。
  • Binder在Framework層進行封裝,通過JNI技術調用Native層的Binder架構
  • 在Native層的Binder以ioctl,open等操作與Binder驅動通訊。

5. Binder原理及步驟

在這裏插入圖片描述

5.1 註冊服務

  • Server創建Binder實體,取一個可讀易記的名字,將Binder實體連同名字以數據包的形式通過Binder驅動發送給ServiceManager,通知ServiceManger註冊這個Binder實體。在這裏Server需要通過0號引用與ServiceManager的Binder進行通訊
  • Binder驅動爲這個穿越邊界的Binder實體在內核空間創建節點和ServiceManager的引用,並將名字和引用打包傳遞給ServiceManager
  • ServiceManager收到數據包後,從中取出名字和引用填入查找表中

5.2 獲取服務

  • Client利用保留的0號引用向ServiceManager請求訪問某個Binder

  • ServiceManager根據請求的數據包獲取Binder名字,在查找表中找到該名字對應的Binder引用

  • 將該引用作爲回覆返回給發起請求的Client

5.2 使用服務

  • Client將進程參數發送到Server進程
  • Binder驅動爲跨進程通信做準備,實現內存映射
  • Server根據Client的參數,執行目標方法
  • Server進程將目標方法的結果返回給Client進程

6. Binder機制的優點

6.1 高效

消息隊列和管道採用的是存儲-轉發方式,至少需要兩次數據拷貝過程,效率比較低。共享內存雖然無需拷貝,但控制複雜,難以使用。而Binder由於使用了內存映射,只需進行一次數據拷貝,效率高

6.2 安全性高

Binder機制爲每個進程分配了UID/PID來鑑別身份的標識,並且在Binder通信時會根據UID/PID進行有效性檢測

6.3 使用簡單,可操作性高

Binder機制採用Client/Server的通信方式,對於管道,共享內存,消息隊列以及Socket來說只有Socket採用了Client/Server的通信方式,但是Socket主要用於跨網絡的進程通信,開銷大,效率低。另外Binder機制還實現了面向對象的調用方式。

7. Android中的IPC方式

7.1 Bundle

兩個使用場景:一是直接利用傳遞數據,在Bundle中附加信息,通過Intent發送出去。二是轉移目標跨進程通信,將需要在A進程計算的任務轉移到B進程的後臺Service中執行。

7.2 文件共享

兩個進程通過讀/寫同一個文件實現交換數據。在這裏需注意的是SharePreferences,它的底層是使用Xml文件來存儲鍵值對,當使用SharePreferences時,內存中會有一份緩存,故在多進程讀寫時,就會出現數據過期的狀況,另外在高併發讀取時,很大機率會出現數據丟失,故不建議在進程通信使用Share Preferences

7.4 Messenger

輕量級IPC,其底層的實現其實是AIDL。首先來看看其工作原理圖
在這裏插入圖片描述

根據工作原理圖來分析其實現過程:

服務進程

  1. 創建一個Service來處理客戶端的連接請求
  2. Service中創建一個Handler來接受客戶端發送過來的消息,並通過這個Handler來創建一個Messenger對象,在onBind中返回Messenger對象的底層binder

客戶進程

  1. 首先綁定Service,綁定成功後利用Service返回的Binder對象創建一個Messenger對象
  2. 通過這個Messenger對象向服務端發送消息,消息類型爲Message

服務進程回覆客戶進程

  1. 當服務進程收到客戶進程的消息後,進行回覆時,則客戶端需在上面的基礎上創建一個Handler來接受服務端的回覆信息,並利用這個Handler對象創建Messenger對象,並把這個對象通過message的reply參數在發送信息時傳遞給服務端。
  2. 服務端在接受到客戶端的信息時,利用攜帶的reply參數得到Messenger對象,然後利用這個對象就可以向客戶端發送message消息類型的消息。

7.5 AIDL

大致流程

首先創建一個Service和AIDL接口,接着創建一個類並繼承AIDL接口中Stub,重寫Stub的抽象方法,在Service中的onBind返回這個類的對象,然後客戶端綁定服務端的Service,綁定成功後將返回的Binder對象轉化成AIDL接口所屬的類型,然後就可以調用接口中的方法。

難點

  1. 支持的數據類型
  • 基本數據類型
  • String和CharSequence
  • List:只支持ArrayList,裏面的元素必須能夠被AIDL支持
  • map:只支持HashMap,鍵值都必須能夠被AIDL支持
  • Parcelable
  • AIDL
  1. AIDL文件中使用到自定義的Parcelable對象都要新建一個和它同名的AIDL文件,只要在文件中聲明那個類爲Parcelable即可
  2. 自定義的Parcelable對象和AIDL對象必須都要顯示import進來
  3. 除基本類型外,其他類型需標上方向,in、out、inout
  4. AIDL接口只支持方法,不支持聲明靜態常量

7.6 ContentProvider

ContentProvider是Android中提供的專門用於不同應用間進行數據共享的方式,故它天生就適合進程間的通訊,和Messenger一樣,它的底層實現也是Binder

7.7 Socket

又稱套接字,網絡通信中的概念。主要分爲流式套接字(TCP)和用戶數據報套接字(UDP)

7.8 Android中各種IPC方式的優缺點

名稱 優點 缺點 適用場景
Bundle 簡單易用 只能傳輸Bundle支持的數據類型 四大組件的進程間的通信
文件共享 簡單易用 不適合高併發場景,無法做到即時通信 無併發訪問情況,交換簡單的數據實時性不高的場景
AIDL 功能強大,支持一對多併發通信,支持實時通信 操作較複雜,需處理好線程同步 一對多通信,有RPC需求
Messenger 支持一對多的串行通信,支持實時通信 不能很好處理高併發情形,不支持RPC,數據通過Message傳遞,故只能傳輸Bundle支持的數據類型 低併發的一對多及時需求,無RPC需求,或者無返回結果的RPC需求
ContentProvider 數據訪問功能強大,支持一對多併發數據共享 受約束的AIDL 一對多的進程間的數據共享
Socket 功能強大,可以通過網絡傳遞字節流,支持一對多實時通信 實現細節繁瑣,不支持直接的RPC 網絡數據交換

參考資料

圖文詳解 Android Binder跨進程通信的原理

操作系統:圖文詳解 內存映射

Android Bander設計與實現

一篇文章瞭解相見恨晚的 Android Binder 進程間通訊機制

《Android開發藝術探索》

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