在不同的進程中, 如何實現傳遞物件呢? 顯然, 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)
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()