如何實現(xiàn)Android接口問題
在不同的進程中, 如何實現(xiàn)傳遞對象呢? 顯然, Java中不允許跨進程內(nèi)存共享, 因此傳遞對象, 只能把對象拆分成操作系統(tǒng)能理解的簡單形式,有關(guān)Android接口的問題下文進行詳細說明。
以達到跨界對象訪問的目的. 在J2EE中,采用RMI的方式, 可以通過序列化傳遞對象. 在Android中, 則采用AIDL的方式. 理論上AIDL可以傳遞Bundle,實際上做起來卻比較麻煩.AIDL(AndRoid接口描述語言)是一種接口描述語言;
編譯器可以通過aidl文件生成一段代碼,通過預(yù)先定義的接口達到兩個進程內(nèi)部通信進程的目的. 如果需要在一個Activity中, 訪問另一個Service中的某個對象, 需要先將對象轉(zhuǎn)化成AIDL可識別的參數(shù)(可能是多個參數(shù)), 然后使用AIDL來傳遞這些參數(shù), 在消息的接收端, 使用這些參數(shù)組裝成自己需要的對象.
AndRoid接口的IPC的機制和COM或CORBA類似, 是基于接口的,但它是輕量級的。它使用代理類在客戶端和實現(xiàn)層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關(guān)類.; 2. 調(diào)用aidl產(chǎn)生的class.
具體實現(xiàn)步驟如下:
1、創(chuàng)建AIDL文件, 在這個文件里面定義接口, 該接口定義了可供客戶端訪問的方法和屬性。 如: ITaskBinder.adil
注意: 理論上, 參數(shù)可以傳遞基本數(shù)據(jù)類型和String, 還有就是Bundle的派生類, 不過在Eclipse中,目前的ADT不支持Bundle做為參數(shù), 據(jù)說用Ant編譯可以, 我沒做嘗試.
2、編譯AIDL文件, 用Ant的話, 可能需要手動, 使用Eclipse plugin的話,可以根據(jù)adil文件自動生產(chǎn)java文件并編譯, 不需要人為介入.
3、在Java文件中, 實現(xiàn)AIDL中定義的接口. 編譯器會根據(jù)AIDL接口, 產(chǎn)生一個JAVA接口。這個接口有一個名為Stub的內(nèi)部抽象類。它繼承擴展了接口并實現(xiàn)了遠程調(diào)用需要的幾個方法。接下來就需要自己去實現(xiàn)自定義的幾個接口了。
- package com.cmcc.demo;
- import com.cmcc.demo.ITaskCallback;
- interface ITaskBinder {
- boolean isTaskRunning();
- void stopRunningTask();
- void registerCallback(ITaskCallback cb);
- void unregisterCallback(ITaskCallback cb);
- }
- 其中: ITaskCallback在文件ITaskCallback.aidl中定義:
- package com.cmcc.demo;
- interface ITaskCallback {
- void actionPerformed(int actionId);
- }
- 注意: 理論上, 參數(shù)可以傳遞基本數(shù)據(jù)類型和String, 還有就是Bundle的派生類, 不過在Eclipse中,目前的ADT不支持Bundle做為參數(shù), 據(jù)說用Ant編譯可以, 我沒做嘗試.
- 2、編譯AIDL文件, 用Ant的話, 可能需要手動, 使用Eclipse plugin的話,可以根據(jù)adil文件自動生產(chǎn)java文件并編譯, 不需要人為介入.
- 3、在Java文件中, 實現(xiàn)AIDL中定義的接口. 編譯器會根據(jù)AIDL接口, 產(chǎn)生一個JAVA接口。這個接口有一個名為Stub的內(nèi)部抽象類,它繼承擴展了接口并實現(xiàn)了遠程調(diào)用需要的幾個方法。接下來就需要自己去實現(xiàn)自定義的幾個接口了.
- ITaskBinder.aidl中接口的實現(xiàn), 在MyService.java中接口以內(nèi)嵌類的方式實現(xiàn):
- private final ITaskBinder.Stub mBinder = new ITaskBinder.Stub() {
- public void stopRunningTask() {
- //@TODO
- }
- public boolean isTaskRunning() {
- //@TODO
- return false;
- }
- public void registerCallback(ITaskCallback cb) {
- if (cb != null) mCallbacks.register(cb);
- }
- public void unregisterCallback(ITaskCallback cb) {
- if (cb != null) mCallbacks.unregister(cb);
- }
- };
- 在MyActivity.java中ITaskCallback.aidl接口實現(xiàn):
- private ITaskCallback mCallback = new ITaskCallback.Stub() {
- public void actionPerformed(int id) {
- //TODO
- printf("callback id=" + id);
- }
- };
4、向客戶端提供AndRoid接口ITaskBinder, 如果寫的是service,擴展該Service并重載onBind ()方法來返回一個實現(xiàn)上述接口的類的實例。這個地方返回的mBinder,就是上面通過內(nèi)嵌了定義的那個. (MyService.java)
【編輯推薦】