系列之一 进程间通信-AIDL实现原理
系列目录
https://blog.csdn.net/jzlhll123/article/category/7671581
作为第一篇文章,选择是很重要的。从目前我研究过的广播,AIDL,Activity等实现机制发现Binder是一个很重要的东西。所以前几篇文章会以学习Binder为主。而Binder的入门,其实,应该从AIDL的使用来分析。
使用:
自己学习写一下Service+AIDL+Parcel,最好能写包含的4种方法:
- void方法;
- 有return值的方法;
- 注册一个带callback;
- 反注册上一个callback。
https://blog.csdn.net/cn_foolishman/article/details/47908227
原理:
找1,2篇AIDL原理相关文章。
https://blog.csdn.net/tgbus18990140382/article/details/52799899
阐述:
我们学习一个东西,第一步要了解如何去用它,然后才能往深里面去研究。AIDL就是一个这样很好的例子。
先从AIDL的创建,编译工具会帮忙自动实现了类来分析。
首先,把定义的aidl文件,自动生成出继承IInterface
的接口这个就是后面client端使用到的服务对象,里面2大块,Stub
和Proxy
(它还是它的静态内部类)。一套是我们定义的方法(就是同一进程属于同一个内存空间,就直接调用了)。另外一套是实现了Binder接口对应的方法。而写代码的时候,Stub
就是service端
里面的一个对象(将方法实现好),在bindService()
的时候给出去。而client端会在onServiceConnected()
的时候,拿到它,当然这里拿到是一个Binder接口IBinder
,需要使用asInterface()
转换成具体的要的对象。就可以使用。上面说的就是我们熟悉使用层面知道的。
接下来来看更多内部的细节。
服务器里面Stub初始化时(一般来说,我们会在service里面new这个对象)就会内部调用attachInterface()
,会保存本地服务的引用后面会用到。然后这里关键的我们将asInterface()
转换成我们自定义的接口。在转换的时候就有意思了。
- 同进程
则直接给出引用即可。 例子就是我们自己的app(同进程下)
中一个activity
来bindService()
的,就会返回这个引用;同进程的调用,同一个内存中:
1. client(这里指的Activity)
2. 调用自定义方法
3. mOwner(引用)调用对应方法;
- 不同进程
client端asInterface()
拿到的就会给出一个proxy
封装后的对象,也就是第二套接口方法。不同进程下,那就需要进入一个大的处理周期了:
1. client 调用某方法
2. Proxy
封装方法名和参数到Parcel
transact()
3. 客户端会挂起, Binder底层进行内存拷贝数据交换
4. 远程service
onTransact()收到了方法的调用
5. service处理完了,_reply
写入parcel结果
6. 最后client
结束挂起。从回复_reply
中拿出return值或者void不拿。
这样才完成了整个周期。
其实我们可以自己实现Binder来编写IPC(进程间通信)
,基本就是实现了IDE/编译器写好的内容。
再往深入,就涉及到Binder了。下一章计划学习下。