什么是aidl
aidl英文全称是Android Interface Definition Language,即Android接口定义语言,AIDL与其他IDL语言类似, 它允许你定义客户端与服务端达成一致的程序接口使用进程间通信相互交流。 在Android上面,一个进程不能正常的访问另一个进程的内存。 所以说,他们需要分解他们的对象为操作系统可以理解的基本单位,然后为你把这些对象按次序跨越进程边界 书写这些代码是单调冗长的,所以android使用AIDL为咱们处理这个问题。
注意:使用AIDL只有在你允许来自不同应用的客户端跨进程通信访问你的service,并且想要在你的service种处理多线程的时候才是必要的。 如果你不需要执行不同应用之间的IPC并发,你应该通过实现Binder建立你的接口,或者如果你想执行IPC,但是不需要处理多线程。那么使用Messenger实现你的接口
aidl所支持的类型
默认支持的数据类型包括:
Java中的八种基本数据类型,包括 byte,int,long,float,double,boolean,char (不支持short类型)
String 类型。
CharSequence类型。
List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable(下文关于这个会有详解)。List可以使用泛型。
Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的
aidl的使用
1,传递基本类型的使用
模拟一种场景,就是在客户端输入两个数,在服务端计算客户端输入的两个数的和然后返回给客户端,客户端用来显示两个数的和
(1)首先在服务端 创建aidl文件,具体步骤如下,如下图所示
点击AIDL Folder 输入aidl,ok即可
(2)在aidl包下创建aidl文件,步骤如下图所示
(3)在aidl文件中写入需要的接口方法并且编译
如果结果如下图所示,则代表编译成功
(4)在服务端写一个service将aidl接口暴露出去
至此服务端的事已经干完了
(5)在客户端中将服务端中的aidl文件复制一份,一定要注意的是包括包名必须要与服务端保持一致,不然会报以下错误 java.lang.SecurityException: Binder invocation to an incorrect interface
(6)当客户端启动的时候通过绑定Service的形式与服务端建立连接
(7)当客户端与服务端绑定之后需要在客户端拿到定义的接口的代理类的对象,然后用代理类的对象调用在aidl文件中定义的方法,返回计算结果并且显示
2,传递自定义类型的使用
模拟一种情景,就是在客户端点击按钮一次,将自定义的一个类型的数据传递到服务端,服务端收到数据之后,将其加入到集合中并且返回
(1)(2)步骤与基本类型相同,不再进行重复
(3)在服务端创建一个Person类,并且实现Parcelable接口,并且手动在该类中定义一个名称叫做CREATOR的变量,必须注意的是名字必须叫这个,并且依次读取在writeToParcel中写入的数据,如下所示
在aidl文件中加入 如下方法 ,并且手动在aidl文件中导入Person的包,比如:import com.example.aidlserver.bean.Person;
编译服务端,会发现报如下错误
这是因为这样写编译器是不认识Person的,必须接入一个aidl文件去描述Person,要注意的是此aidl文件必须要与Person类的包名保持一致,如下所示
至此服务端的工作就做完了
(4)将刚才在服务端写入的aidl文件和Person类拷贝一份到客户端,注意包名保持一致
(5)在客户端调用服务端,步骤与基本类型一致,不再赘述了,运行结果如下所示
源码地址:https://github.com/zhanmusi2323/AidlClient