架構之Binder 核心原理(一)

什麼是Binder

binder是Android中特有的一種跨進程的實現方式,模糊了進程邊界,淡化了進程通訊的過程,整個系統彷彿運行在OOP的程序中,Binder彷彿是粘貼各種應用程序的 “膠水”,英文中binder的意思就是"膠水"。Binder無處不在,就好比在OOP中,調用的時候使用binder就可以拿到其他的一些進程服務。如媒體播放,音視頻捕獲,手機傳感器,加速度,方位,溫度,亮度,甚至startActivity/Service等等,都是由不同的服務端 Server 提供一些服務,供應用程序調用,而應用程序作爲客戶端與提供服務的Server建立鏈接,便可以方便的使用這些服務。

Binder與AIDL關係

平時項目中,如果純粹使用Binder調動系統服務,代碼量會非常大,非常複雜。而AIDL是一種架構,爲我們使用Binder的時候提供更加輕便簡潔的語法就可以調用Binder,實現跨進程的通信。
AIDL是專門爲Binder設計的一種框架, 如果單純用Binder來調用系統提供的服務,代碼量會非常大、非常複雜,而AIDL是一中框架,提供給開發者更加輕便的解決跨進程方案,AIDL只是封裝了。如startActivity封裝了AIDL,一行代碼實現了跨進程。

Binder更貼切的比喻

在這裏插入圖片描述
如上圖:

  • Binder :系統提供了很多服務應用程序調用,而Binder作爲了調用這些服務的接入點
  • Client :應用程序作爲client,調用系統提供的服務,可以通過binder,在client而言,binder可以看做通向服務管道的入口

域名發佈的時候,就會告訴DNS(域名解析服務器)真實ip地址。

Binder由來

linux內核提供了很多進程間通信(IPC)的嘗試方式。如下

linux提供的通訊方式 缺點 其他
管道 耗費性能 半雙工,如對講機;全雙工,如電話
共享內存 使多個進程訪問同一塊內存空間,管理混亂。
socket 適用於網絡通訊,但對於進程間通訊大材小用。 適用於網絡通信

A進程與B進程通信:

  • 管道:首先A打開管道,B打開管道,A往管道中寫數據,進程B從管道中讀數據,不停地寫不停地讀,直到寫完之後,進程A再關閉通道,進程B關閉通道,最後刪除管道。 這個過程很 消耗性能。
  • 共享內存 : 多個進程可以同時共享同一塊內存空間,但是管理很混亂。
  • socket :更加適用於網絡通信,但對於進程間通訊大材小用。

在這裏插入圖片描述
上圖中,數據會進行至少2次拷貝。
Android應用程序之間,是不可以進行數據共享的,而在底層內核空間就可以。

Android 爲什麼用Binder進行 ipc,

binder會對通信的應用雙方進行身份校驗,安全性高。
android系統會爲每一個應用程序分配一個唯一的UID,進程的UID是鑑別進程身份的重要標識。

驗證pid(進程id) uid(用戶id)。
傳輸效率高,binder驅動的內核區域進行數據拷貝,只會拷貝一次。
性能僅次於共享內存。
binder基於c/s架構(一對多)
爲發送方添加了pid,uid(Android9.0源碼startActivity有體現,待驗證)。

爲什麼學binder

Binder四個重要的角色:Server , Client ,ServiveManager , Binder驅動,前三者存在於用戶空間,而Binder驅動存在於內核空間。而用戶空間(client)是不可以進程通信的,內核空間可以。
在這裏插入圖片描述

ServiveManager服務主要是作爲ServerClient之間的橋樑,ServiceManagerinit進程中啓動,類比於DNS。Client可以通過ServiceManager拿到Server中Binder實體的引用。如有服務需要提供給client,那需要將binder的引用註冊到ServiceManager中。如client想要使用該服務,需要固定的key(類比於域名www.baidu.com)及binder引用來訪問該服務。從ServiceManager的map鏈表提取出來,通過key拿到對應的binder引用。

Android中,很多服務都是通過Binder去和AMS進行交互的。如獲取音量服務。

AudioManager audioManager = (AudioManager) getSystemService(Service.AUDIO_SERVICE);

系統提供的很多服務Server,如手機傳感器、加速度等等,都需要在ServiveManager中進行註冊,多個系統服務在ServiveManager中進行註冊。此時,ServiveManager作爲服務端,而Server作爲客戶端。

// 當一個進程使用 binder.setContext

Binder驅動:負責進程之間Binder 通訊的建立,binder之間無法直接進行交互,都是+通過Binder驅動進行通訊。binder驅動中有一個線程池,因爲可能存在併發,線程池由binder驅動管理。一個進程中,binder的線程池中線程數最大是16,超過這請求就會阻塞等待空閒。

ThreadPool:多個需求方需要用個同一個服務或多個服務的時候就產生很多binder驅動的交互。

AIDL

AIDL: Android Interface Definition Language

Client 與 Server進行通信的時候,必須統語言,否則無法進行通信。而AIDL專門爲這種通信 設計的一種架構,用來binder之間通信。

Binder四個重要對象:

Binder角色 作用 說明
IBinder 接口,代表了跨進程通訊的能力,只要實現改接口就可以進行跨進程傳輸了。
IInterface 代表了Server進程對象具備哪些功能,提供哪些方法,對應了AIDL定義的接口
Binder java層的Binder類,代表了Binder的本地對象,BinderProxy是Binder內部類。 繼承自IBinder
Stub AIDL的時候,idea自動生成一個stub的靜態內部類,繼承了Binder,實現了IInterface接口 具備Serve承諾給Client的一種能力

Binder : client訪問server提供的服務的時候,並不是直接操作binder對象而是操作binder引用,並且是通過本地代理BinderProxy 去 操作binder驅動操作來訪問Server,完成之後BinderProxy 就會和內核的內存映射存在共存(共享內存?有待商榷)關係。如下圖:
在這裏插入圖片描述

無論Binder還是BinderProxy都是繼承自IBinder因而皆具備跨進程通信的能力。

Binder機制通信的流程:

在這裏插入圖片描述

在這裏插入圖片描述

總結:

在這裏插入圖片描述
架構設計:
在這裏插入圖片描述
client 代用 代理BinderProxy接口的方法時候,會將Client傳遞的數據打包成Parcel

Parcel Parcelable Searilable區別

架構之Binder 核心原理(二)

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