Android-Binder机制
http://www.jianshu.com/p/af2993526daf
https://www.jianshu.com/u/e347b97e2f0c
上面这篇文章讲得很清楚。以下我的一些理解:
还是先说应用再说原理。
1.应用
以AIDL远程service为例,整个过程是这样的:
- 服务端定义AIDL文件,里面包含想提供给客户端的函数定义
- rebuild自动生成一个接口文件
- 服务器端定义自己的service,初始化stub实现函数,在onbind()返回stub
- 服务器端startService()
- 客户端实现ServiceConnection类并在其中调用函数
- 客户端bindService()
2.原理
Binder机制跨进程原理
binder机制实现跨进程的思路是:
- 先有一个serviceManager负责管理所有的service
- 实现服务器端,然后向SM注册,说明我有什么功能,接受远程调用
- 客户端向SM查询xx进程里的xx对象
- SM向客户端返回一个对象代理
- 客户端把想做的事告诉对象代理
- 对象代理把数据转交给Binder驱动(SM)
- Binder驱动把数据给服务器,叫他做这个事
- 服务器把结果返回给Binder驱动,驱动再返回给客户端
在实现上这些步骤是怎么样的,源码可以看一开始的链接,这边依旧是给我的理解。
概念:
IBinder/IInterface/Binder/BinderProxy/Stub
我们使用AIDL接口的时候,经常会接触到这些类,那么这每个类代表的是什么呢?
- IBinder是一个接口,它代表了一种跨进程传输的能力;只要实现了这个接口,就能将这个对象进行跨进程传递;这是驱动底层支持的;在跨进程数据流经驱动的时候,驱动会识别IBinder类型的数据,从而自动完成不同进程Binder本地对象以及Binder代理对象的转换。
- IBinder负责数据传输,那么client与server端的调用契约(这里不用接口避免混淆)呢?这里的IInterface代表的就是远程server对象具有什么能力。具体来说,就是aidl里面的接口。
- Java层的Binder类,代表的其实就是Binder本地对象。BinderProxy类是Binder类的一个内部类,它代表远程进程的Binder对象的本地代理;这两个类都继承自IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder驱动会自动完成这两个对象的转换。
- 在使用AIDL的时候,编译工具会给我们生成一个Stub的静态内部类;这个类继承了Binder, 说明它是一个Binder本地对象,它实现了IInterface接口,表明它具有远程Server承诺给Client的能力;Stub是一个抽象类,具体的IInterface的相关实现需要我们手动完成,这里使用了策略模式。
下面就是实现的流程:
在AIDL接口文件中我们会写提供使用的函数定义,假设AIDL中的接口名称为A。方法为ADD,rebuild后自动生成的代码结构是这样的:
- A接口继承IInterface(提供远程server对象具有什么能力)
- ADD()
- 内部stub类继承Binder
内部stub类结构:
- asInterface(),判断是否远程,返回Binder或新创建的BinderProxy
- OnTransact(),接收Binder驱动发来的数据,调用相应函数,将结果返回给驱动
- 内部Proxy类
内部Proxy类结构:
- ADD(),接收客户端数据,把数据序列化,调用transact()把数据发给Binder驱动,然后挂起等待Binder驱动返回的数据
步骤一先不谈
步骤二:实现服务器端,然后向SM注册,说明我有什么功能,接受远程调用
这里包括
- 定义AIDL接口并rebuild
- 在AndroidManifest注册
- 自定义service,实现stub中的函数
- 启动service
步骤三:客户端向SM查询xx进程里的xx对象
步骤四:SM向客户端返回一个对象代理
- 客户端实现ServiceConnection
- 调用asInterface(),判断是否远程,返回Binder或新创建的BinderProxy。这里是BinderProxy
步骤五:客户端把想做的事告诉对象代理
步骤六:对象代理把数据转交给Binder驱动(SM)
- 调用BinderProxy里的函数,调用transact()把数据发给Binder驱动,然后挂起等待Binder驱动返回的数据
步骤七:Binder驱动把数据给服务器,叫他做这个事
步骤八:服务器把结果返回给Binder驱动,驱动再返回给客户端
- 调用OnTransact(),接收Binder驱动发来的数据,调用相应函数,将结果返回给驱动
系统服务进程之间的通信
http://www.jianshu.com/p/9b8e787a9bd3
总体思路:
再去翻阅系统的ActivityManagerServer的源码,就知道哪一个类是什么角色了:
IActivityManager是一个IInterface,它代表远程Service具有什么能力
ActivityManagerNative指的是Binder本地对象(类似AIDL工具生成的Stub类),这个类是抽象类,它的实现是ActivityManagerService
;因此对于AMS的最终操作都会进入ActivityManagerService
这个真正实现;
同时如果仔细观察,ActivityManagerNative.java里面有一个非公开类ActivityManagerProxy, 它代表的就是Binder代理对象;是不是跟AIDL模型一模一样呢?那么ActivityManager
是什么?他不过是一个管理类而已,可以看到真正的操作都是转发给ActivityManagerNative
进而交给他的实现ActivityManagerService
完成的。