Android中的Binder機制
什麼是Binder?
其實在實際開發中,我們可能很少直接的使用到Binder,但是卻間接的一直在用它,只是我們沒有在意。比如當我們啟動一個Activity呼叫startActivity的時候,在系統的內部其實通過Binder機制呼叫了ActivityManagerService中的startActvity方法。
那到底什麼是Binder呢?從IPC的角度來說,Binder是跨程序通訊的一種方式。何為跨程序通訊?要理解Binder之前,我們先了解一下Linux程序基礎。
Linux程序基礎
我們都知道Android是基於Linux系統的,在Linux系統中,為了保護程序空間不被幹擾,程序之間是相互獨立的(也叫程序隔離)。而且一個程序空間還分為使用者空間和核心空間,它們倆也是隔開的。綜上所述,這裡有兩個隔離,一個是程序之間的隔離,一個是程序空間內的使用者和核心的隔離。
既然有隔離,那麼它們之間就有相互配合的時候,也就是它們需要互動。程序之間的互動也叫程序之間的通訊(IPC,或者我們說的跨程序通訊),程序空間內使用者空間和核心的互動,叫做系統呼叫。
也就是說,為了保護程序的安全性和獨立性,一個程序是不能直接操作或者訪問另一個程序空間的,既然我們都知道Android系統是架設在Linux基礎之上的,所以肯定也需要解決這個問題。也就是說需要一種跨程序通訊的方式,當然跨程序通訊的方式有很多種,其中Binder就是一種跨程序通訊的方式,那麼在Android系統中為什麼要使用Binder作為跨程序通訊呢?
為什麼要使用Binder?
在傳統的Linux上,我們還是有很多選擇可以用來實現程序之間通訊的。如管道,SystemV、Socket等。而為什麼不選擇這些原有的技術,而是選擇開發一種新的叫Binder的程序通訊機制呢?主要有兩大原因:效能和安全方面
(1)在效能方面,Binder相對於傳統的Socket方式更加高效。Binder的資料拷貝只需要一次,而管道,訊息佇列,Socket都需要兩次。共享記憶體方式需要一次拷貝,但是實現起來太複雜。
(2)在安全方面,在傳統的程序之間通訊方式,對雙方的身份並沒有做出嚴格的校驗,比如Socket通訊的ip是客戶端填寫的,很容易偽造。而Binder本身支援對通訊雙方身份的校驗。因此大大的提升了安全性。
Binder的執行機制
Binder是基於client-server通訊模式。在Binder通訊中主要有四個角色。
Client:客戶端,也就是使用服務的程序。
Server:服務端,也就是提供服務的程序。
ServiceManager:ServiceManager的作用是將字元形式的Binder的名字轉化成Client對該Binder的引用。也就使得Client能通過Binder的名字來獲得Server中Binder實體的引用。
Binder驅動:負責程序之間Binder通訊的建立。
可能我們對上面這四個角色很陌生。我們可以用傳統的網際網路打個比喻:
Client就是我們傳統的客戶端,Server就是伺服器,ServiceManager就是域名伺服器(DNS,也就是將域名轉換成IP地址,使得客戶端可以通過域名的方式訪問伺服器,而不用直接訪問IP),Binder驅動,也就是我們的路由器了,負責建立通訊。
通過一張圖,更加直觀的瞭解一下。

image.png
從圖中我們可以更加直觀的瞭解Binder的原理。
我們看到Server註冊服務和Client獲取服務都不是直接從ServiceManager直接互動的,可以看到上面是虛線的。他們之間通過Binder驅動建立連線。
所以主要流程可以小結為:
(1)Server通過Binder驅動向ServiceManager註冊服務。
(2)Client通過Binder驅動獲取服務。
在實際開發中,我們很少用到Binder,但是理解Binder的原理,對於我們理解整個Android系統體系會有進一步的認識。下一篇文章我們將介紹在實際開發中用到Binder的例子——AIDL。