Framework篇 - 彻底理解 Binder 通信架构

本文源代码基于 Android 7.0。

 

目录:

  1. Binder 分层架构
  2. startService 分析 Binder
  3. 通信流程分析 Binder

 

 

1. 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。

 

 

2. startService 分析 Binder

Binder 系统如此庞大,那么这里需要寻求一个出发点来穿针引线,一窥视 Binder 全貌。那么本文将从全新的视角,以startService 流程分析为例子来说说 Binder 所其作用。首先在发起方进程调用 AMP.startService,经过 Binder 驱动,最终调用系统进程 AMS.startService,如下图:

 

start server binder:

AMP 和 AMN 都是实现了 IActivityManager 接口,AMS 继承于 AMN。其中 AMP 作为 Binder 的客户端,运行在各个 app 所在进程,AMN (或 AMS) 运行在系统进程 system_server。

Binder IPC 原理 Binder 通信采用 C/S 架构,从组件视角来说,包含 Client、Server、ServiceManager 以及 Binder 驱动,其中ServiceManager 用于管理系统中的各种服务。下面说说 startService 过程所涉及的 Binder 对象的架构图: 

 


 

可以看出无论是注册服务和获取服务的过程都需要 ServiceManager,需要注意的是此处的 ServiceManager 是指 Native 层的ServiceManager (C++), 并非指 framework 层的 ServiceManager (Java)。ServiceManager 是整个 Binder 通信机制的大管家,是 Android 进程间通信机制 Binder 的守护进程,Client 端和 Server 端通信时都需要先获取 ServiceManager 接口,才能开始通信服务,当然查找到目标信息可以缓存起来则不需要每次都向 ServiceManager 请求。

图中 Client/Server/ServiceManage 之间的相互通信都是基于 Binder 机制。既然基于 Binder 机制通信,那么同样也是 C/S 架构,则图中的 3 大步骤都有相应的 Client 端与 Server 端。

  • 注册服务:首先 AMS 注册到 ServiceManager。该过程:AMS 所在进程 (systemserver) 是客户端,ServiceManager 是服务端。
  • 获取服务:Client 进程使用 AMS 前,须先向 ServiceManager 中获取 AMS 的代理类 AMP。该过程:AMP 所在进程 (app process) 是客户端,ServiceManager 是服务端。
  • 使用服务:app 进程根据得到的代理类 AMP,便可以直接与 AMS 所在进程交互。该过程:AMP 所在进程 (app process) 是客户端,AMS 所在进程 (systemserver) 是服务端。 图中的 Client,Server,Service Manager 之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与 Binder Driver 进行交互的,从而实现 IPC 通信方式。 其中 Binder 驱动位于内核空间,Client,Server,Service Manager 位于用户空间。Binder 驱动和 Service Manager 可以看做是 Android 平台的基础架构, 而Client 和 Server 是 Android 的应用层。

这 3 大过程每一次都是一个完整的 Binder IPC 过程。

 

 

3. 通信流程分析 Binder

 

 

发起端线程向 Binder Driver 发起 binder ioctl 请求后,便采用循环不断 talkWithDriver,此时该线程处于阻塞状态,直到收到如下BRXXX 命令才会结束该过程。

  • BRTRANSACTIONCOMPLETE:oneway 模式下,收到该命令则退出;
  • BRREPLY:非 oneway 模式下,收到该命令才退出;
  • BRDEADREPLY:目标进程/线程/binder 实体为空,以及释放正在等待 reply 的 binder thread 或者binder buffer;
  • BRFAILEDREPLY: 情况较多,比如非法handle, 错误事务栈, security, 内存不足, buffer不足, 数据拷贝失败, 节点创建失败, 各种不匹配等问题;
  • BRACQUIRERESULT: 目前未使用的协议,左图中 waitForResponse 收到 BRTRANSACTIONCOMPLETE,则直接退出循环,则没有机会执行 executeCommand() 方法;

除以上 5 种 BRXXX 命令,当收到其他 BR 命令,则都会执行 executeCommand 过程。目标 Binder 线程创建后,便进入joinThreadPool() 方法, 采用循环不断地执行 getAndExecuteCommand() 方法, 当 bwr 的读写 buffer 都没有数据时,则阻塞在binderthreadread 的 waitevent 过程。另外,正常情况下 binder 线程一旦创建则不会退出。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值