AIDL: android interface definition language. 实现进程间通信(IPC)。
以Client端调用Server端的求和方法为例以作说明。
- 首先,Server端(单独的一个module),使用AS右键新建一个aidl文件,叫IRemoteService.aidl,这里它会自动创建src/main/aidl目录,aidl与java语法类似,写一个add()方法。
- 接着sync一下,此时在module根目录/build/generated/source/aidl/debug/pkg name下面会自动生成IRemoteService文件,里面有接下来要用到的Stub。
- Server端新建一个java文件RemoteService继承Service,重写onBind()方法,该方法的返回值默认是IBinder类型,这个iBInder对象就可以由之前生成的IRemoteService.Stub产生了,如图:
远程服务创建完成,Client调用时只需要bindService即可调用RemoteService中的方法了,具体过程继续。
- Client端(单独的一个module),要实现计算a+b的和,界面很简单,只需要三个EditText:分别显示两个加数和远程调用返回的和,以及一个Button,进行远程方法的调用。
- 这里我希望我的Client端app一启动立刻绑定远程Service,所以在MainActivity的onCreate方法中,执行以下操作:
//获取到服务端
Intent intent = new Intent();
//5.0新版本 必须显式Intent启动 绑定服务
intent.setComponent(new ComponentName("com.xkc.computeserver",
"com.xkc.computeserver.RemoteService"));
bindService(intent, conn, Context.BIND_AUTO_CREATE);
需要注意的是,Android 5.0以上不允许使用隐式Intent,这里使用显式启动,开发者官网上有详细说明,最后bindService, flag为自动创建,里面的conn是ServiceConnection对象,感觉像是绑定服务连接的一个回调,创建ServiceConnection对象:
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//当绑定上服务的时候
//拿到远程服务(其实只是远程服务的一个代理)
iRemoteService = IRemoteService.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
//当服务断开的时候
//回收资源
iRemoteService = null;
}
};
这样,当服务建立起连接时,拿到远程服务的代理,当服务断开时,回收远程服务资源。
此时,远程服务已经可用,可以通过iRemoteService调用远程服务的add方法了。
int num1 = Integer.parseInt(et_num1.getText().toString());
int num2 = Integer.parseInt(et_num2.getText().toString());
try {
//调用远程服务
int res = iRemoteService.add(num1,num2);
et_res.setText(res + " ");
} catch (RemoteException e) {
e.printStackTrace();
et_res.setText("出错");
}
现在只是一个很简单的小例子,至于背后的Binder机制,需要以后更多的积累。