Android 手寫 Binder 教你理解 android 中的程式間通訊

發表於2016-07-22

關於Binder,我就不解釋的太多了,網上一搜資料一堆,但是估計還是很多人理解的有困難。今天就教你如何從 app層面來理解好Binder。

其實就從我們普通app開發者的角度來看,僅僅對於android應用層的話,Binder就是客戶端和服務端進行通訊的媒介。

AIDL就是我們理解Binder 最好的事例。

我們都知道 我們寫好aidl 檔案以後,開發工具 會自動幫我們生成好程式碼。實際上 我們最終apk裡面 是隻有這些程式碼的,我們寫的aidl檔案

是不會被打包進去的,也就是說aidl檔案 實際上 就是我們用來 生成 實際binder程式碼用的。所以 我們只要能夠分析好,ide自動幫我們生成的

程式碼,就可以自己手寫binder,從而在app層面上真正理解binder的用法和含義 以及原理。

首先我先來定義一個實體類:Person.java

注意看  我們這個person 類 是實現了android自帶的序列化介面的,所以 如果你要在aidl裡使用這個類,那你必須要額外在aidl裡生命下 這個類。

好,然後給你們看一下 檔案結構:

365799-20160127102641192-2048181583

好 這裡就是一個典型的 應用aidl 技術的 一個例子,我們現在 讓studio 編譯這個project,然後看看生成的binder程式碼。 把這份binder程式碼 分析好了,我們以後就可以不借助ide 來自己手寫binder了。

我們來看看 生成的程式碼在哪裡:

365799-20160127102944270-903968755

最後我們來看一下 這個生成的程式碼 是啥樣的:

看上去呢,雜亂無章, 但其實也就是100多行,所以 我調整了一下 這個程式碼的順序 ,你們可以看的更清楚,同時也增加了註釋:

到這裡 相信大家 至少在應用層上面,就對Binder就一個很直觀的理解了,對於程式間通訊來說,具體的流程就分為如下幾步:

1.Client 發起遠端呼叫請求 也就是RPC 到Binder。同時將自己掛起,掛起的原因是要等待RPC呼叫結束以後返回的結果

2.Binder 收到RPC請求以後 把引數收集一下,呼叫transact方法,把RPC請求轉發給service端。

3.service端 收到rpc請求以後 就去執行緒池裡 找一個空閒的執行緒去走service端的 onTransact方法 ,實際上也就是真正在執行service端的 方法了,等方法執行結束 就把結果 寫回到binder中。

4.Binder 收到返回資料以後 就喚醒原來的Client 執行緒,返回結果。至此,一次程式間通訊 的過程就結束了

搞明白以後 我們就可以來嘗試著 手下一下Binder:(前面我們aidl 幫我們生成的binder 是人,也就是person,那這次我們自己寫的時候 就用狗吧,用DOG)

首先定義一個Dog.java: 實際上和person 一樣的 所以這裡暫時把程式碼摺疊起來。

然後寫一個介面IDogManager

然後寫我們的binder,注意我們的binder 我這裡是寫的抽象類,因為你寫成實體類的話 就必須要實現IDogManger裡的2個方法 ,然而為了結構清晰 我們並不準備把binder 放在service裡 實現。

所以這裡binder 我們還是用抽象類來做,然後在service裡 實現 getDogList和addDog方法即可。

到這,我們的手寫binder 就完成了,然後看看 service 以及客戶端 怎麼呼叫。

先看service:

然後看看 啟動如何在客戶端bind 這個service:

到這 就基本寫完了,手寫binder的好處就是 你可以自己在binder方法裡 寫一些log,能夠更加深刻的認識到 Binder 作為 程式間通訊 媒介的重要作用以及原理。

熟悉以後,還是用aidl 的方法 自動生成程式碼 最好。

相關文章