1. 使用步骤
AIDL 的意思是 Android 接口定义语言。利用它来定义进程间通信时双方认可的编程接口。
第一步:创建 .aidl 文件
AIDL 接口方法中支持的参数类型:
- 8 个基本数据类型
- String
- CharSequence
- List:List 中的所有元素必须是以上支持的数据类型、其他 AIDL 生成的接口或自定义的 Parcelable 类型。接收端实际接受的具体类始终是 ArrayList,但生成的方法使用 List 接口。
- Map:Map 中元素要求和 List 一样。接收端实际接受的具体类始终是 HashMap,但生成的方法使用 Map 接口。
以上没有列出的每个附加的类型(AIDL、Parcelable)都要加入 import 语句,即使是在同一包中定义。
// IRemoteService.aidl
package com.mindle.androidtest;
// Declare any non-default types here with import statements
import com.mindle.androidtest.IRemoteServiceCallback;
interface IRemoteService {
void registerCallback(in IRemoteServiceCallback callback);
}
对于自定义的 Parcelable 对象,还要创建 MyParcelable.aidl 文件,然后在 AIDL 接口中引用该包。如下:
package com.android.demo.parcelable;
parcelable MyParcelable;
package <package_name>;
import com.android.demo.parcelable;
interface IDemo {
void demoMethod(in MyParcelable myParcelable);
}
除了基本数据类型,其他类型的参数必须标上方向:in, out, inout。
aidl接口只支持方法,不支持声明静态常量。
build 之后,在同一包下,系统自动生成同名的 .java 文件。
第二步:实现接口
以下采用匿名实例实现了自动生成的抽象类 ISecondary.Stub 中的方法,mSecondaryBinder 是 Stub 类的实例(一个 Binder),用于定义服务的远程通信接口。下一步中,需要向客户端公开该实例。
private final ISecondary.Stub mSecondaryBinder = new ISecondary.Stub() {
@Override
public int getPid() throws RemoteException {
return Process.myPid();
}
};
注意:默认情况下,客户端调用 mSecondaryBinder 的方法是同步调用,所以要考虑是否开启新的线程。
第三步:向客户端公开该接口
通过将 AIDL 包中的 .aidl
文件拷贝到客户端应用的 src/
目录,使得客户端能够访问这些接口。在服务的 onBind 方法中,返回 AIDL 的具体实现。
@Override
public IBinder onBind(Intent intent) {
// Return the interface
return mSecondaryBinder;
}
客户端绑定上服务后,客户端的 onServiceConnected() 回调会接收服务的 onBind() 方法返回的 mSecondaryBinder 实例,它必须调用 YourServiceInterface.Stub.asInterface(service)
以将返回的参数转换成 YourServiceInterface
类型。如下示例:
ISecondary mSecondaryService;
private ServiceConnection mSecondaryConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mSecondaryService = ISecondary.Stub.asInterface(service);
}
@Override