一. 首先在服务端创建一个和java文件夹同级的aidl文件夹,然后在aidl文件夹里面新建AIDL接口,在接口里面定义我们要暴露给客户端调用的方法,AIDL接口中的数据类型只能是八大基本数据类型丶String和CharSequence丶List和Map(里面的元素都必须能够被AIDL支持)丶实现了Parcelable接口的对象以及AIDL接口本身.AIDL接口的示例代码如下:
// IMyAidlInterface.aidl
package com.gh.demo;
// Declare any non-default types here with import statements
import com.gh.demo.User;
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
int getSum(int a,int b);
User getUser();
}
(注意:自定义的User类型不仅需要实现Parcelable接口,还需要在aidl文件中声明一个同名的User.aidl文件)
package com.gh.demo;
parcelable User;
写完AIDL接口文件一定要记得点一下sync project按钮!让as帮我们生成AIDL接口类.这个接口类里面主要有一个Stub抽象类和一个静态Proxy类,其中Stub类是要在服务端的Service中实现并返回Binder对象给客户端,客户端通过这个Binder对象来调用服务端的方法,而Proxy类则是一个代理类,因为客户端并不是直接调用服务端的方法的,而是通过Proxy代理类来间接调用服务端的方法.
二. 新建一个Service,并且实现AIDL接口中的定义的方法,直接new AIDL接口中的Stub类就可以,因为这个类是继承Binder的,所以就是将这个binder对象返回给客户端,其实进程间通信就是基于Binder来实现的,示例代码如下:
public class AidlService extends Service {
public AidlService() {
}
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
private IBinder iBinder = new IMyAidlInterface.Stub() {
// 供客户端调用
@Override
public int getSum(int a, int b) throws RemoteException {
return (a+b)*10;
}
// 供客户端调用
@Override
public User getUser() throws RemoteException {
User user= new User();
user.age = 100;
user.name = "张三";
return user;
}
};
}
三. 服务端的aidl配置完毕,接着把服务端的整个aidl文件夹以及自定义的User类复制到客户端,这里需要注意一个坑,自定义的User类的包名一定要与服务端的User类所在的包名一致,复制完AIDL相关的文件到客户端后,接着就是和正常的绑定Service方法是一样的,区别就是Intent要通过setCompoment()来指定要启动其它进程组件,关键代码如下:
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 将服务端返回的Binder对象转换为Aidl接口对象以通过Proxy类去调用服务端的方法
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
iMyAidlInterface = null;
}
};
//在需要与服务端通信的地方调用这个方法即可连接服务端实现进程间通信
private void toBindAidlService(){
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.gh.demo","com.gh.demo.AidlService"));
boolean isBind = bindService(intent,serviceConnection,BIND_AUTO_CREATE);
Log.e("是否绑定成功", String.valueOf(isBind));
//绑定服务端Service成功后就可以调用服务端的方法了
Log.e("调用服务端getSum方法", String.valueOf(iMyAidlInterface.getSum(4,1)));
Log.e("调用服务端getUser方法",iMyAidlInterface.getUser().toString());
}
安装服务端程序(其实不需要打开也可以),安装启动客户端程序,运行看一下Logcat的日志
可以见得已成功实现了AIDL进程间通信.