IPC(跨进程通信) 的方式有很多种,例如 socket、共享内存、管道、消息队列等等
这篇文章重点讲解Binder以及和binder相关的aidl使用。
Binder
从android代码中来看,Binder是一个实现了IBinder接口的类,在跨进程通信中Binder是一种通信方式。Binder在android Framework层是各种Manager和ManagerService的桥梁,在应用层,提供了客户端与应用端的一种连接方式。
Binder是一种代理模式,创建一个IManager接口类继承IInterface,IInterface中里写的是需要的method,会有一个Stub类继承Binder并实现IManager,这个类是运行在服务端的类。
Stub类下还有一个Proxy代理类,这个类实现了IManager接口,并且在类的内部有一个IBinder对象,这个对象是stub的实例,客户端会得到这个代理类的实例,客户端调用method,method中这个IBinder对象调用transact方法。
在Binder类中transact方法会调用onTransact方法。
这个IBinder对象已经知道是服务端的一个实例,那么onTransact 方法也是在服务端进行的,onTransact中会区分出要进行的方法调用method的空实现,这个空实现在创建实例的时候会进行重写在其中写入你要进行的操作,这个实现在服务端。
那么Binder的整个过程也就完成了。但是我们发现在Binder类中还有一个BinderProxy类,这个类是个final类不可被继承,我通过断点测试发现当Service与当前Activity处于不同的进程时,onServiceConnected方法中传入的IBinder对象是一个BinderProxy对象,那么传入Proxy类中的IBinder对象也就是一个BinderProxy实例,这时我们就会发现到其实真正的跨进程并不是我们上边所提到的这个流程,上边我们所讲的流程是处在同一进程的Service和Activity发生BindService时的流程,那么BinderProxy与Binder的区别是什么呢,还是通过代码来进行查看,通过代码我们发现BinderProxy涉及到了与C++层的交互,通过C++层调用到服务器端的onTransact(也就是stub的),这里再完整的捋一遍这个过程,当Service和Activity不再同一进程时,onServiceConnected方法会接收到一个BinderProxy实例,并将实例给到Stub.Proxy的IBinder对象,这时触发method,method中触发BinderProxy.transact方法,经过C++层的代码,调用Stub的transact方法,调用Stub的onTransact方法,方法中调用到Service中的method完成操作,返回结果。这时Stub.Proxy的method接收到结果并返回。
至此整个跨进程通讯的过程也就分析完成,aidl的流程跟上边分析的过程是一样的,只不过系统会帮助我们生成Stub和Proxy类,让我们省去了一些工作。
还有一些细节有待完善,比如监听Service的死亡等,后期会完善。