翻译作者地址: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原文地址:这里写链接内容