天天看點

Android AIDL使用詳解

1.什麼是aidl:aidl是 Android Interface definition language的縮寫,一看就明白,它是一種android内部程序通信接口的描述語言,通過它我們可以定義程序間的通信接口

icp:interprocess communication :内部程序通信

2.既然aidl可以定義并實作程序通信,那麼我們怎麼使用它呢?文檔/android-sdk/docs/guide/developing/tools/aidl.html中對步驟作了較長的描述:

--1.Create your .aidl file - This file defines an interface (YourInterface.aidl) that defines the methods and fields available to a client. 

建立你的aidl檔案,我在後面給出了一個例子,它的aidl檔案定義如下:寫法跟java代碼類似,但是這裡有一點值得注意的就是它可以引用其它aidl檔案中定義的接口,但是不能夠引用你的java類檔案中定義的接口

package com.cao.android.demos.binder.aidl;    

import com.cao.android.demos.binder.aidl.AIDLActivity;  

interface AIDLService {     

    void registerTestCall(AIDLActivity cb);     

    void invokCallBack();  

}    

--2.Add the .aidl file to your makefile - (the ADT Plugin for Eclipse manages this for you). Android includes the compiler, called AIDL, in the tools/ directory. 

編譯你的aidl檔案,這個隻要是在eclipse中開發,你的adt插件會像資源檔案一樣把aidl檔案編譯成java代碼生成在gen檔案夾下,不用手動去編譯:編譯生成AIDLService.java如我例子中代碼

Android AIDL使用詳解

--3.Implement your interface methods - The AIDL compiler creates an interface in the Java programming language from your AIDL interface. This interface has an inner abstract class named Stub that inherits the interface (and implements a few additional methods necessary for the IPC call). You must create a class that extends YourInterface.Stub and implements the methods you declared in your .aidl file. 

實作你定義aidl接口中的内部抽象類Stub,public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService

Stub類繼承了Binder,并繼承我們在aidl檔案中定義的接口,我們需要實作接口方法,下面是我在例子中實作的Stub類:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

private final AIDLService.Stub mBinder = new AIDLService.Stub() {  

    @Override  

    public void invokCallBack() throws RemoteException {  

        Log("AIDLService.invokCallBack");  

        Rect1 rect = new Rect1();  

        rect.bottom=-1;  

        rect.left=-1;  

        rect.right=1;  

        rect.top=1;  

        callback.performAction(rect);  

    }  

    public void registerTestCall(AIDLActivity cb) throws RemoteException {  

        Log("AIDLService.registerTestCall");  

        callback = cb;  

};  

Stub翻譯成中文是存根的意思,注意Stub對象是在被調用端程序,也就是服務端程序,至此,服務端aidl服務端得編碼完成了。

--4.Expose your interface to clients - If you're writing a service, you should extend Service and override Service.onBind(Intent) to return an instance of your class that implements your interface. 

第四步告訴你怎麼在用戶端如何調用服務端得aidl描述的接口對象,doc隻告訴我們需要實作Service.onBind(Intent)方法,該方法會傳回一個IBinder對象到用戶端,綁定服務時不是需要一個ServiceConnection對象麼,在沒有了解aidl用法前一直不知道它是什麼作用,其實他就是用來在用戶端綁定service時接收service傳回的IBinder對象的:

AIDLService mService;  

private ServiceConnection mConnection = new ServiceConnection() {  

    public void onServiceConnected(ComponentName className, IBinder service) {  

        Log("connect service");  

        mService = AIDLService.Stub.asInterface(service);  

        try {  

            mService.registerTestCall(mCallback);  

        } catch (RemoteException e) {  

        }  

    public void onServiceDisconnected(ComponentName className) {  

        Log("disconnect service");  

        mService = null;  

mService就是AIDLService對象,具體可以看我後面提供的示例代碼,需要注意在用戶端需要存一個服務端實作了的aidl接口描述檔案,但是用戶端隻是使用該aidl接口,不需要實作它的Stub類,擷取服務端得aidl對象後mService = AIDLService.Stub.asInterface(service);,就可以在用戶端使用它了,對mService對象方法的調用不是在用戶端執行,而是在服務端執行。

4.aidl中使用java類,需要實作Parcelable接口,并且在定義類相同包下面對類進行聲明:

上面我定義了Rect1類

之後你就可以在aidl接口中對該類進行使用了

package com.cao.android.demos.binder.aidl;  

import com.cao.android.demos.binder.aidl.Rect1;

interface AIDLActivity {   

    void performAction(in Rect1 rect);   

}  

注意in/out的說明,我這裡使用了in表示輸入參數,out沒有試過,為什麼使用in/out暫時沒有做深入研究。

5.aidl使用完整示例,為了清除說明aidl使用,我這裡寫了一個例子,例子參考了部落格:

javascript:void(0)

作出說明

例子實作了一個AIDLTestActivity,AIDLTestActivity通過bindservice綁定一個服務AIDLTestService,通過并擷取AIDLTestActivity的一個aidl對象AIDLService,該對象提供兩個方法,一個是registerTestCall注冊一個aidl對象,通過該方法,AIDLTestActivity把本身實作的一個aidl對象AIDLActivity傳到AIDLTestService,在AIDLTestService通過操作AIDLActivity這個aidl遠端對象代理,使AIDLTestActivity彈出一個toast

文章倉促而成,有什麼疑問歡迎大家一起讨論。