在上一篇关于Android进程间通信中介绍了Android的三种进程间通信的方式。这里再介绍一种牛逼的IPC方式
AIDL
上次去面试一家心仪的公司,面试官有问道关于Android多进程通信相关的方法,我吧能想到的全都说了,但是没有说道一个让面试官满意的方式。是的,面试官要的答案就是AIDL实现进程间的通信。
上一篇文章中介绍的三种方式都有自己的局限性和缺点(这个在后面还会总结一下)
那么AIDL呢?近乎完美。
关于AIDL是什么,可以Google一下。这里我只给出自己对AIDL的理解:
一种实现进程间通信的方式。
IDE(eclipse 或者 studio)都会根据aidl文件自动生成对应的Java文件,实现接口的作用
在不同的进程之间实现序列化和反序列化同一个对象
可实现观察者模式的进程间通信
一个注意点:在Android studio中创建的aidl文件,studio会自动创建一个aidl文件夹,然后该文件夹下的类不能被Java文件夹下的类访问,需作如下处理:
修改gradle文件
|
|
ok准备工作已经做好,开始你的表演
1 服务端与客户端的通信
同样分为服务端和客户端
1.1 aidl文件
在项目中创建一个专门的aidl包,里面放与aidl相关的文件,方便新进程中复制。
新建一个Books类,实现Parcelable接口让他可序列化。
Books.java代码
然后建立一个Books.aidl文件,和一个IBookManager.aidl文件
Books.aidl代码
|
|
IBookManager.aidl代码
说明一下:在使用Bundle 或者Messenger实现进程间通信的时候在传递序列化对象时由于进程间无法共享类,所以会导致class not find 报错。这里aidl解决了这个问题。我们要做的是让两个进程能有相同的Books对象(只是相同的对象示例,不是同一个)在两个进程中都要写有相同的aidl文件(将服务端的aidl文件夹整个复制到客户端即可)
1.2服务端
服务端创建一个Service用来监听客户端的链接请求,然后创建一个AIDL文件,将暴露给客户端的接口在AIDL中申明,最后在Service中实现这个AIDL接口
实现代码:
|
|
可以看到,在服务端我们实例化一个CopyOnWriteArrayList对象mBookList,实现IBookManager接口,然后添加了两个book。还有要做的就是建立aidl文件夹及Books相关的aidl文件。
下面看看客户端的代码实现
1.3客户端
记得把Books相关aidl文件包全部烤过来。
BookManagerActivity代码:
|
|
这样在启动BookManagerActivity的时候就会启动BookManagerService服务,并且实现了通信,跟接口使用一样一样的。
2 AIDL 实现观察者模式
牛逼哄哄的观察者模式
提到接口的使用,那么我们可能会想到监听事件,也就是观察者模式。比如有这样的需求:每当service里面增加一本书,客户端就重新获取一次books列表。并且要求客户端可以监听和取消监听。
为了知道服务端添加了新书,我们需要写一个新的aidl接口IOnNewBookArrivedListener
IOnNewBookArrivedListener.aidl代码:
|
|
为了能够注册监听和取消监听,我们需要对IBookManager.aidl进行改进,新增两个方法registerListener,和unregisterListener
修改后的代码如下:
IBookManager.aidl代码
|
|
注意导包,即使在同一个包下也要导入。
2.1服务端
接下来实现服务端每5秒钟添加一本书。
BookManagerService.java代码
|
|
看到ServiceWorker这个Runnable,完成了每隔5秒添加一个新的books对象。再看到onNewBookArrived方法。先在mBookList添加新书,然后遍历了mListenerList,之所以遍历mListenerList是因为该服务是可以实现一对多的交互的,也就是说,如果有多个客户端,那么服务端是要通知每个服务端新书到了的消息的。示例中只有一个客户端,所以这里的mListenerList.size为1.
其他的也没什么好说的,代码很简洁明了。就是增加了监听接口。
2.2 客户端修改
BookManagerActivity.java
|
|
看下改动了那些东西.
- 定义一个Handler对象mHandle处理接收信息
- 创建IOnNewBookArrivedListener接口对象onNewBookArrivedListener,mHandle处理接口的newBook。
- bookManager添加了registerListener 参数为onNewBookArrivedListener。
- 在activity 销毁的时候注销了监听。
看了这个流程似乎就清晰了很多。代码里面还是有点绕。
但是!!! 当退出activity的时候去发现控制台输出了如下打印
|
|
也就是说解除注册失败了!
欲知后事,请看下回