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如我例子中程式碼
--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類:
- 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);
- }
- @Override
- 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使用,我這裡寫了一個例子,例子參考了部落格:
http://blog.csdn.net/saintswordsman/archive/2010/01/04/5130947.aspx
作出說明
例子實現了一個AIDLTestActivity,AIDLTestActivity通過bindservice繫結一個服務AIDLTestService,通過並獲取AIDLTestActivity的一個aidl物件AIDLService,該物件提供兩個方法,一個是registerTestCall註冊一個aidl物件,通過該方法,AIDLTestActivity把本身實現的一個aidl物件AIDLActivity傳到AIDLTestService,在AIDLTestService通過操作AIDLActivity這個aidl遠端物件代理,使AIDLTestActivity彈出一個toast,完整例子見我上傳的資源:
http://download.csdn.net/source/3284820
文章倉促而成,有什麼疑問歡迎大家一起討論。
source:http://blog.csdn.net/stonecao/article/details/6425019