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