翻譯作者地址:http://su1216.iteye.com/%20http://blog.csdn.net/su1216/
AIDL一般都用在需要比較複雜的跨進程/線程通信場合。比如自己的程序需要用一個Service去處理各種事務,而又需要跟Service能相互調用的場合。要注意的是AIDL不是線程安全的,如有這方面需要的話就要自己處理好臨界情況。
使用AIDL只有在你允許來自不同應用的客戶端跨進程通信訪問你的service,並且想要在你的service種處理多線程的時候纔是必要的。 如果你不需要執行不同應用之間的IPC併發,你應該通過實現Binder建立你的接口,或者如果你想執行IPC,但是不需要處理多線程。那麼使用Messenger實現你的接口 不管怎樣,確保你在實現一個AIDL之前理解了Bound Service
下面以客戶端A應用調用B應用爲例
1.定義一個AIDL接口
創建一個以.aidl結尾的文件。打開創建的文件,使用java語言定義一個接口,接口只包含接口聲明和方法簽名。如下
// IRemoteService.aidl
package com.example.android;
/** Example service interface */
interface IRemoteService {
//接口聲明
int getPid();
//方法聲明(方法可以接收0或多個參數,並且有返回值或者返回void)
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat);
}
保存.aidl文件在src目錄下
2.實現接口
當你編譯你的應用時,Android SDK工具生成一個.java接口文件用你的.aidl文件命名 生成的接口包含一個名字爲Stub的子類(比如YourInterface.Stub),這是一個它父類的抽象實現,並且聲明瞭.aidl中所有的方法
//IRemoteService.Stu是IBinder的子類
private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
public int getPid(){
return Process.myPid();
}
public void basicTypes(int anInt, long aLong, boolean aBoolean,
float aFloat, double aDouble, String aString) {
// Does nothing
}
};
3.暴露接口給客戶端
一旦你爲service實現了接口,你需要把它暴露給客戶端,這樣他們才能綁定到上面 爲了給你的service暴露接口,繼承Service並且實現onBind()方法返回一個你實現生成的Stub類(像我們在上一結討論的那樣) 這有一個service暴露IRemoteService接口給客戶端的例子
public class RemoteService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// Return the interface
return mBinder;
}
private final IRemoteService.Stub mBinder = new IRemoteService.Stub()
{
public int getPid(){
return Process.myPid();
}
public void basicTypes(int anInt, long aLong, boolean aBoolean,
float aFloat, double aDouble, String aString) {
// Do something(執行邏輯)
}
};
}
在B應用的manifes中,service的相關配置片段
<service android:name="com.zhangxikai.RemoteService">
<intent-filter >
<action android:name="com.zahngxikai.aidl"/>
</intent-filter>
</service>
通過以上三步我們完成了被調用端B的工作。
現在,當一個客戶端(比如一個activity)調用bindService()來連接到這個service,這個客戶端的onServiceConnected()回調函數接收service中onBind()方法返回的mBinder實例
客戶端必須可以訪問接口類,所以如果客戶端和服務端在不同的應用中,那麼客戶端所在的應用必須有一份.aidl文件的副本在其src目錄下(生成android.os.Binder接口,提供客戶端訪問AIDL方法都在這個目錄下)
當客戶端在onServiceConnected()回調方法中接收到IBinder時,它必須調用你的ServiceInterface.Stub.asInterface(service)來把返回參數映射到你的ServiceInterface類型上。例如:
IRemoteService mIRemoteService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
//獲取接口
mIRemoteService = IRemoteService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "Service has unexpectedly disconnected");
mIRemoteService = null;
}
};
在A應用中調用B應用的basicTypes方法
Intent intent = new Intent();
intent.setAction("com.zahngxikai.aidl");
bindService(intent,mConnection,BIND_AUTO_CREATE);
//調用B應用中的相關函數(最終目的)
mIRemoteService.basicTypes(....參數);
Android中文api原文地址:這裏寫鏈接內容