Android - Binder通信架构
- Java应用层: 对于上层应用通过调用AMP.startService, 完全可以不用关心底层,经过层层调用,最终必然会调用到AMS.startService.
- Java IPC层: Binder通信是采用C/S架构, Android系统的基础架构便已设计好,Binder在Java framework层的Binder客户类,BinderProxy和服务类Binder;
- Native IPC层: 对于Native层,如果需要直接使用Binder(比如media相关), 则可以直接使用BpBinder和BBinder(当然这里还有JavaBBinder)即可, 对于上一层Java IPC的通信也是基于这个层面.
- Kernel物理层: 这里是Binder Driver, 前面3层都跑在用户空间,对于用户空间的内存资源是不共享的,每个Android的进程只能运行在自己进程所拥有的虚拟地址空间, 而内核空间却是可共享的. 真正通信的核心环节还是在Binder Driver.
通过startService的流程分析如图
AMP和AMN都是实现了IActivityManager接口,AMS继承于AMN. 其中AMP作为Binder的客户端,运行在各个app所在进程, AMN(或AMS)运行在系统进程system_server.
Binder IPC原理
Binder
通信采用C/S
架构,从组件视角来说,包含Client、Server、ServiceManager
以及binder驱动,其中ServiceManager用于管理系统中的各种服务.
可以看出无论是注册服务和获取服务的过程都需要ServiceManager
,需要注意的是此处的Service Manager
是指Native
层的ServiceManager
(C++),并非指framework
层的ServiceManager
(Java)。ServiceManager
是整个Binder
通信机制的大管家,是Android进程间通信机制Binder的守护进程,Client端和Server端通信时都需要先获取Service Manager接口,才能开始通信服务, 当然查找到目标信息可以缓存起来则不需要每次都向ServiceManager请求。
- 注册服务:首先AMS注册到ServiceManager。该过程:AMS所在进程(system_server)是客户端,ServiceManager是服务端。
- 获取服务:Client进程使用AMS前,须先向ServiceManager中获取AMS的代理类AMP。该过程:AMP所在进程(app process)是客户端,ServiceManager是服务端。
- 使用服务: app进程根据得到的代理类AMP,便可以直接与AMS所在进程交互。该过程:AMP所在进程(app process)是客户端,AMS所在进程(system_server)是服务端。
Client,Server,Service Manager
之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与Binder Driver
进行交互的,从而实现IPC通信方式.
Binder驱动位于内核空间,Client,Server,Service Manager
位于用户空间。Binder驱动和Service Manager可以看做是Android平台的基础架构,而Client和Server是Android的应用层.
通信原理
发起端线程向Binder Driver发起binder ioctl请求后, 便采用环不断talkWithDriver,此时该线程处于阻塞状态, 直到收到如下BR_XXX命令才会结束该过程.
- BR_TRANSACTION_COMPLETE: oneway模式下,收到该命令则退出
- BR_REPLY: 非oneway模式下,收到该命令才退出;
- BR_DEAD_REPLY: 目标进程/线程/binder实体为空, 以及释放正在等待reply的binder thread或者binder buffer;
- BR_FAILED_REPLY: 情况较多,比如非法handle, 错误事务栈, security, 内存不足, buffer不足, 数据拷贝失败, 节点创建失败, 各种不匹配等问题
- BR_ACQUIRE_RESULT: 目前未使用的协议;
左图中waitForResponse收到BR_TRANSACTION_COMPLETE,则直接退出循环, 则没有机会执行executeCommand()方法, 故将其颜色画为灰色. 除以上5种BR_XXX命令, 当收到其他BR命令,则都会执行executeCommand过程.
目标Binder线程创建后, 便进入joinThreadPool()方法, 采用循环不断地循环执行getAndExecuteCommand()方法, 当bwr的读写buffer都没有数据时,则阻塞在binder_thread_read的wait_event过程. 另外,正常情况下binder线程一旦创建则不会退出.
通信协议
- Binder客户端或者服务端向Binder Driver发送的命令都是以BC_开头,例如本文的
BC_TRANSACTION
和BC_REPLY
, 所有Binder Driver向Binder客户端或者服务端发送的命令则都是以BR_开头, 例如本文中的BR_TRANSACTION
和BR_REPLY
. - 只有当
BC_TRANSACTION
或者BC_REPLY
时, 才调用binder_transaction()来处理事务. 并且都会回应调用者一个BINDER_WORK_TRANSACTION_COMPLETE
事务, 经过binder_thread_read()会转变成BR_TRANSACTION_COMPLETE
. - startService过程便是一个非oneway的过程, 那么oneway的通信过程如下所述.
- Java应用层: 对于上层应用通过调用AMP.startService, 完全可以不用关心底层,经过层层调用,最终必然会调用到AMS.startService.
- Java IPC层: Binder通信是采用C/S架构, Android系统的基础架构便已设计好,Binder在Java framework层的Binder客户类,BinderProxy和服务类Binder;
- Native IPC层: 对于Native层,如果需要直接使用Binder(比如media相关), 则可以直接使用BpBinder和BBinder(当然这里还有JavaBBinder)即可, 对于上一层Java IPC的通信也是基于这个层面.
- Kernel物理层: 这里是Binder Driver, 前面3层都跑在用户空间,对于用户空间的内存资源是不共享的,每个Android的进程只能运行在自己进程所拥有的虚拟地址空间, 而内核空间却是可共享的. 真正通信的核心环节还是在Binder Driver.
通过startService的流程分析如图
AMP和AMN都是实现了IActivityManager接口,AMS继承于AMN. 其中AMP作为Binder的客户端,运行在各个app所在进程, AMN(或AMS)运行在系统进程system_server.
Binder IPC原理
Binder
通信采用C/S
架构,从组件视角来说,包含Client、Server、ServiceManager
以及binder驱动,其中ServiceManager用于管理系统中的各种服务.
可以看出无论是注册服务和获取服务的过程都需要ServiceManager
,需要注意的是此处的Service Manager
是指Native
层的ServiceManager
(C++),并非指framework
层的ServiceManager
(Java)。ServiceManager
是整个Binder
通信机制的大管家,是Android进程间通信机制Binder的守护进程,Client端和Server端通信时都需要先获取Service Manager接口,才能开始通信服务, 当然查找到目标信息可以缓存起来则不需要每次都向ServiceManager请求。
- 注册服务:首先AMS注册到ServiceManager。该过程:AMS所在进程(system_server)是客户端,ServiceManager是服务端。
- 获取服务:Client进程使用AMS前,须先向ServiceManager中获取AMS的代理类AMP。该过程:AMP所在进程(app process)是客户端,ServiceManager是服务端。
- 使用服务: app进程根据得到的代理类AMP,便可以直接与AMS所在进程交互。该过程:AMP所在进程(app process)是客户端,AMS所在进程(system_server)是服务端。
Client,Server,Service Manager
之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与Binder Driver
进行交互的,从而实现IPC通信方式.
Binder驱动位于内核空间,Client,Server,Service Manager
位于用户空间。Binder驱动和Service Manager可以看做是Android平台的基础架构,而Client和Server是Android的应用层.
通信原理
发起端线程向Binder Driver发起binder ioctl请求后, 便采用环不断talkWithDriver,此时该线程处于阻塞状态, 直到收到如下BR_XXX命令才会结束该过程.
- BR_TRANSACTION_COMPLETE: oneway模式下,收到该命令则退出
- BR_REPLY: 非oneway模式下,收到该命令才退出;
- BR_DEAD_REPLY: 目标进程/线程/binder实体为空, 以及释放正在等待reply的binder thread或者binder buffer;
- BR_FAILED_REPLY: 情况较多,比如非法handle, 错误事务栈, security, 内存不足, buffer不足, 数据拷贝失败, 节点创建失败, 各种不匹配等问题
- BR_ACQUIRE_RESULT: 目前未使用的协议;
左图中waitForResponse收到BR_TRANSACTION_COMPLETE,则直接退出循环, 则没有机会执行executeCommand()方法, 故将其颜色画为灰色. 除以上5种BR_XXX命令, 当收到其他BR命令,则都会执行executeCommand过程.
目标Binder线程创建后, 便进入joinThreadPool()方法, 采用循环不断地循环执行getAndExecuteCommand()方法, 当bwr的读写buffer都没有数据时,则阻塞在binder_thread_read的wait_event过程. 另外,正常情况下binder线程一旦创建则不会退出.
通信协议
- Binder客户端或者服务端向Binder Driver发送的命令都是以BC_开头,例如本文的
BC_TRANSACTION
和BC_REPLY
, 所有Binder Driver向Binder客户端或者服务端发送的命令则都是以BR_开头, 例如本文中的BR_TRANSACTION
和BR_REPLY
. - 只有当
BC_TRANSACTION
或者BC_REPLY
时, 才调用binder_transaction()来处理事务. 并且都会回应调用者一个BINDER_WORK_TRANSACTION_COMPLETE
事务, 经过binder_thread_read()会转变成BR_TRANSACTION_COMPLETE
. - startService过程便是一个非oneway的过程, 那么oneway的通信过程如下所述.