AIDL进程间通信
- 简介
- 项目结构
- 服务端
- 客户端
简介
aidl:android interface definition language(安卓接口定义语言),主要用于安卓系统中的跨进程通信。
项目结构
aidlserver:服务端,包含aidl、service、序列化的实体类。
aidlclient:客户端,包含aidl、实体类、绑定service代码。
服务端
1. 创建aidl文件。
在android studio创建一个服务端(注:本博客中所有所说的服务端和客户端都是相对的,因为安卓系统中的每一个项目都可以充当服务端和客户端,只是为了说明aidl才这么称呼它们)项目,本例中项目名称为aidlserver。
首先创建aidl文件:在项目名称右键—>New—>AIDL—>AIDL File,Android Studio可以自动创建aidl目录和文件。
2. 定义ICalculator接口。
写一个方法int add(int a, int b),该方法计算两个参数的和作为返回值,写完该aidl后点击Sync按钮同步一下工程,可以自动生成ICalculator.java文件。
interface ICalculator {
/**
* 加法计算
*/
int add(int a, int b);
}
3. 创建服务。
创建RemoteServer,根据ICalculator.java的Stub方法生成IBinder对象,在重写的add方法中写这个方法的逻辑。
ICalculator.java中有一个Stub抽象类,这个抽象类继承自Binder,实现了ICalculator接口,创建这个抽象类的对象向上转型为IBinder对象,在创建的抽象类中重写add方法,这个方法里就是操作客户端传来的两个参数的逻辑,本例中是计算它们的和然后返回。
private IBinder iBinder = new ICalculator.Stub() {
@Override
public int add(int a, int b) throws RemoteException {
return a + b;
}
};
重写service的onBind方法,在该方法中返回上一步生成的iBinder。
@Override
public IBinder onBind(Intent intent) {
//绑定service后返回ibinder
Log.d(TAG, "RemoteServer onBind");
return iBinder;
}
客户端
1. 创建aidl文件
在android studio创建一个客户端项目,本例中项目名称为aidlclient。
因为客户端的aidl文件包名需要与服务端一致,所以与服务端创建aidl文件不同的是,客户端需要先创建aidl目录,在该目录下创建服务端包名,然后创建aidl文件,该文件内容与服务端完全一致。在创建完成该文件后,同样需要同步工程。
2. 创建ServiceConnection
在activity中绑定service,在绑定成功的onServiceConnected回调中创建ICalculator对象。
ICalculator.java中有一个DESCRIPTOR字段,该字段就是创建的aidl包名+文件名,根据该字段判断IBinder参数是否是DESCRIPTOR对应的接口的实例,是则返回强转的对象,否则返回代理类。
private ICalculator iCalculator;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "serviceConnection onServiceConnected");
iCalculator = ICalculator.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "serviceConnection onServiceDisconnected");
iCalculator = null;
}
};
3. 绑定service
Intent intent = new Intent();
intent.setComponent(new ComponentName("cn.qiiyue.aidlserver", "cn.qiiyue.aidlserver.RemoteServer"));
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
4. 接收结果
在此处调用add方法,服务端的逻辑进行计算,返回结果。
int result = iCalculator.add(1, 2);
Log.d(TAG, "result: " + result);