Binder 机制入门
黑线过程:是作为服务端的注册服务过程。
蓝线过程:是作为客户端获取服务的过程。
红线过程:是客户端使用服务端服务的过程。
这里有几个概念需要了解一下。
Binder 驱动和 ServiceManager
我的理解是系统中的两个模块,「Binder 驱动」用于实现内存映射相关的东西,这里就当它是个转换器。是 Binder 机制的一部分,如果觉得名称里包含 Binder 觉得别扭,可以就叫「转换器」之类的。「ServiceManager」用于管理服务,例如注册服务过程就会把新注册的服务存起来,方便客户端访问时取出。
IInterface
系统提供的一个接口,如果服务端要对外提供服务,就要自己定义接口并集成这个接口才算 Binder 机制的一部分。否则,自定义的接口只是一个普通接口,不能用于进程间通信。
IBinder
系统提供的一个接口,描述的是一个远程通信的抽象协议,意思就是定义了跨进程通信是怎么做的,例如数据怎么传递啊,支持什么类型啊,这些类似的东西。它是 Binder 机制的核心部分,不能直接继承或实现,得用 Binder。
Binder
这个 Binder 是实实在在的 Binder 类,实现了 IBinder 接口。可以理解为(客户端,Binder 驱动,服务端)交互的介质对象,也是对远程通信协议的具体实现。不过一般不会直接用它,因为涉及到具体业务相关的数据传递,会采用子类继承 Binder 来实现。
服务端注册
结合上面这几个概念,可以完成黑线过程。即 1.定义好服务端要提供的服务功能接口。2.定义好服务端的 Binder 实体,用于存放在 ServiceManager,供后面进程间通信。可以定义一个抽象类,继承自 Binder,并实现步骤 1 中的接口;也可以先定义一个抽象类继承自 Binder,再定义一个类继承自刚才的抽象类并实现接口。3.定义一个服务,即定义一个类继承自 Service,这个就是用来暴露步骤1提供的服务功能,客户端是通过 bindService 的形式进行访问的。
通过对客户端绑定服务的启动流程的了解 从 Binder 通信机制角度谈 bindService 的启动流程 我们知道,Service 的 onBind 方法应该返回服务端的 Binder 实体,而在此之前服务端应该已经向 ServiceManager 注册好功能服务了,也就是 attachInterface 方法执行完毕。因为只有调用了这个方法,后续才能通过 queryLocalInterface 方法查询相应的功能服务。参考文章中的代码是在 Binder 实体类的构造方法中完成了 attach,并在 Service 的 onBind 方法中创建 Binder 实体对象,我们也暂且这样。
客户端建立服务连接
对客户端来说主要就是在合适的位置调用 bindService 方法,并实现方法入参,重点是实例化 ServiceConnection 并在方法 onServiceConnected 回调后,拿到服务端的 Binder 实体对象引用(这里有个概念要区分开,即如果客户端和服务端在同一进程,那么 IBinder 对象确实是服务端的 Binder 实体,如果不在同一进程,那么 IBinder 对象就是 BinderProxy 实体,与服务端的通信实际要借助代理完成)。不管哪种情况客户端最终都能拿到指定的功能服务,即接口形式的引用。这个过程就可以理解为上图中的蓝线过程。
至于黑线过程,则是客户端在持有接口形式的服务引用之后,根据业务调用相应方法的过程。
关于 BinderProxy 相关的东西还需要再梳理,还不知道怎么就变成 BinderProxy 了,Service 的 onBind 方法里明明创建的是 Binder 类型,这里暂且记住,如果是两个进程间通信,在 Service 的 onServiceConnected 方法里获取到的 IBinder 类型其实是 BinderProxy 对象,后续需要我们转为代理类对象来进行后续操作;如果是同一进程就不需要进行转化了,当然这个 IBinder 类型任然为 BinderProxy 对象。
参考文章
Android跨进程通信:图文详解 Binder机制 原理
Android Binder原理剖析
Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析