Binder機制(4)

純Native的Service

純Native的Service表示代碼都在Native層。Native層有很多Service,前面的MS不就是一個重量級的嗎?

假設Service叫ITest,我們該如何實現呢?完全可以模仿MS!具體實現過程如下所示:



Test是怎麼定義的呢?我們是跨進程的C/S,所以本地需要一個BnTest,對端需要提供一個代理BpTest。爲了不暴露Bp的身份,Bp的定義和實現在放在BnTest.cpp中了。


1. 我能幹什麼

ITest接口表明了它所提供的服務,例如getTest和setTest等,這個與業務邏輯相關,代碼如下所示:


2. 定義BnTest和BpTest

爲了把ITest融入到Binder系統,需要定義BnTest和對客戶端透明的BpTest。BnTest定義既可以與上面的Test定義放在一塊,也可以分開,如下所示:


另外,我們還要使用IMPLEMENT宏。參考BnMediaPlayerService的方法,把BnTest的BpTest的實現都放在ITest.cpp中,如下所示:



BpTest也在這裏實現。如下所示:




純Native的Service寫起來量大一些,上面的代碼還只是把C/S的框架寫好了,真正的業務處理尚未開始,不過感覺卻很踏實,很厚重。那麼Java層的Service該怎麼寫呢?


扶得起的“阿斗”(aidl)

阿斗(aidl的諧音)本來是扶不起的,可是我們有了AIDL工具,就有可能將他扶起!

1. 我能幹什麼?

在Java層中,如果想要利用Binder進行跨進程的通信,也得定義一個類似ITest的接口,不過這是一個aidl文件。現在假設服務端程序都在com.test.service包中。

ITest.aidl文件的內容如下:


定義完後。如果使用Eclipse進行編譯,會在gen目錄下生成一個com.test.ITest.java文件(也會生在對應包結構的目錄)。

2. 實現服務端:

com.test.ITest.java只是實現了類似BnTest的一個東西,具體的業務實現還需要從ITest.Stub派生,實現代碼如下所示:



這時,你的Eclipse下會有如下目錄:

1. src下有一個com.test.service包結構目錄

2. gen下也有一個com.text.service包結構目錄,其中的內容是由aidl工具生存的


3. 實現代理端

代理端往往在另外一個程序中使用。假設是com.test.client包,把剛纔com.test.service工程中的gen下的com.test.service目錄全部複製到com.test.client中了。這樣,client工程也就有兩個包結構目錄了:

1. com.test.client

2. com.test.service。 不過這個目錄中僅有aidl生成的Java文件。


服務端一般駐留在Service進程中,所以可以在Client端的onServiceConnected函數中獲得代理對象,實現代碼如下:



4. 傳遞複雜的數據結構

AIDL支持簡單數據結構與Java中String類型的數據進行跨進程傳遞,如果向做到跨進程傳遞複雜的數據結構,還需另做一些工作。

以ITest.aidl文件中使用的complicatedDataStructure爲例:

1. 它必須實現implements Parcelable接口

2. 內部必須有一個靜態的CREATOR類。

3. 定義一個coplicatedDataStructure.aidl文件

可參考Android API文檔的parcelable類,裏面有一個很簡單的例子。


來看着個Java文件的實現:




complicatedDataStructure.aidl該怎麼寫呢?如下所示:


然後在使用它的aidl文件中添加下行代碼即可:


有了AIDL,再看我們的阿斗是不是能扶得起了呢?當然,想讓上面的程序正確工作,還得再努力,把未盡的業務層事業完成。另外,還要經得起殘酷環境的考驗(即通過測試來檢驗自己的程序)。


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