Binder機制優點
進程架構:
Android的進程架構:每一個Android進程都是獨立的,且都由兩部分組成,一部分是用戶空間,另一部分是內核空間,如下圖:
如此設計的優點:
- 穩定性、安全性高:每一個Android進程都擁有自己獨立的虛擬地址空間,一方面可以限制其他進程訪問自己的虛擬地址空間;另一方面,當一個進程崩潰時不至於“火燒連營”。
- 便於複用與管理:內核共享有助於系統維護和併發操作、節省空間。
優點有:
- 傳輸效率高: 傳輸效率主要影響因素是內存拷貝的次數,拷貝次數越少,傳輸速率越高;Binder拷貝次數爲1
- 可操作性強
- 安全性高:傳統Linux IPC的接收方無法獲得對方進程可靠的UID/PID,從而無法鑑別對方身份;而Binder機制爲每個進程分配了UID/PID且在Binder通信時會根據UID/PID進行有效性檢測。
幾種數據傳輸方式比較:
方式 | 拷貝次數 | 操作難度 |
---|---|---|
Binder | 1 | 簡單 |
消息隊列 | 2 | 簡單 |
Socket | 2 | 簡單 |
管道 | 2 | 簡單 |
共享內存 | 0 | 複雜 |
從Android進程架構角度分析:對於消息隊列、Socket和管道來說,數據先從發送方的緩存區拷貝到內核開闢的緩存區中,再從內核緩存區拷貝到接收方的緩存區,一共兩次拷貝,如圖:
而對於Binder來說,數據從發送方的緩存區拷貝到內核的緩存區,而接收方的緩存區與內核的緩存區是映射到同一塊物理地址的,節省了一次數據拷貝的過程,如圖:
由於共享內存操作複雜,綜合來看,Binder的傳輸效率是最好的。
Binder框架及原理
Binder框架定義了四個角色:Server,Client,ServiceManager和Binder驅動。
其中Server、Client、ServiceManager運行於用戶空間,Binder驅動運行於內核空間。關係如圖:
客戶端和服務端如何完成連接
- ServiceManager:服務的管理者,將Binder名字轉換爲Client中對該Binder的引用,使得Client可以通過Binder名字獲得Server中Binder實體的引用。流程如圖:
- Server服務器端:在服務端創建好了一個Binder對象後,內部就會開啓一個線程用於接收Binder驅動發送的消息,收到消息後會執行onTranscat(),並按照參數執行不同的服務端代碼。
- Binder驅動:
與硬件設備沒有關係,其工作方式與設備驅動程序是一樣的,工作於內核態。
提供open()、mmap()、poll()、ioctl()等標準文件操作。在服務端成功Binder對象後,Binder驅動也會創建一個mRemote對象(也是Binder類),客戶端可藉助它調用transcat()即可向服務端發送消息。 - Client客戶端:客戶端要想訪問Binder的遠程服務,就必須獲取遠程服務的Binder對象在Binder驅動層對應的mRemote引用。當獲取到mRemote對象的引用後,就可以調用相應Binder對象的暴露給客戶端的方法。
客戶端和服務端如何交互(Binder 工作原理)
- 服務器端:在服務端創建好了一個Binder對象後,內部就會開啓一個線程用於接收Binder驅動發送的消息,收到消息後會執行onTranscat(),並按照參數執行不同的服務端代碼。
- Binder驅動:在服務端成功Binder對象後,Binder驅動也會創建一個mRemote對象(也是Binder類),客戶端可藉助它調用transcat()即可向服務端發送消息。
- 客戶端:客戶端要想訪問Binder的遠程服務,就必須獲取遠程服務的Binder對象在Binder驅動層對應的mRemote引用。當獲取到mRemote對象的引用後,就可以調用相應Binder對象的暴露給客戶端的方法。