加AIDL(Android Interface Definition Language)是一种接口定义语言,可用于在Android设备上,进行进程之间的通信。主要实现是,一个进程作为服务端,提供数据或数据接口,另一个进程作为客户端,通过绑定的service来获取服务端提供的数据或数据接口,达到进程的通信。
注意:仅当您允许不同应用中的客户端访问针对 IPC 的服务时,并且希望在服务中处理多线程时,才需要使用 AIDL。如果您不需要跨不同应用执行并发 IPC,请通过实现 Binder 来创建接口。如果您希望执行 IPC,但不需要处理多线程,请使用 Messenger 实现接口。无论如何,在实现 AIDL 之前,请务必先了解绑定服务。
1、创建AIDL文件
AIDL文件的分类:
- 申明实现Parcel able接口的数据类型以提供其他AIDL文件使用那些分默认支持的数据类型
- 自定义接口方式,申明要爆露的方法给客户端调用。在AIDL中需明确说明引用的数据类型和所在包名,两个文件须在相同包名下。
支持的数据类型:
- 八种基本数据类型:byte、char、short、int、long、float、double、boolean
- String,CharSequence
- List类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
- Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
创建AIDL文件,服务端和客户端都需要创建,以服务端为例,客户端,复制一份即可,首先创建两个module,一个模拟服务端,一个模拟客户端,并创建AIDL文件
注意高版本studio,需要先在module的build.gradle中设置aidl为ture,不然无法创建AIDL文件,如下:
创建成功后,文件结构如下:
2、实现接口
创建AIDL文件后,通过build工程后,系统会通过Android sdk工具生成一个aidl同名的java文件,并生成一个Stub的子类,是其父接口的抽象实现。
定义接口
这里我创建了一个实体类,学生信息,作为数据传递载体
接口实现,并公开接口,供客户端使用
3、注册服务
4、客户端调用
首先客户端需要复制一份服务端的aidl文件,并且保持目录一致,如下:
客户端通过调用bindservice()连接此服务,这里我们用Intent方式,设置服务的包名和action。
并且获得onBind()方法返回的binder实例,调用其方法。如下:
private IStudentManager iStudentManager;
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
// Following the example above for an AIDL interface,
// this gets an instance of the IRemoteInterface, which we can use to call on the service
iStudentManager = IStudentManager.Stub.asInterface(service);
try {
iStudentManager.addStudentInfoReq(new StudentInfo("张三",150,150));
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
// Log.e(TAG, "Service has unexpectedly disconnected");
iStudentManager = null;
}
};
到这里,aidl的通信就完成了。