基本原理

Binder 的通信模型有 4 个角色:Binder Client、Binder Server、Binder Driver(Binder 驱动)、ServiceManager。


ServiceManager、Binder Client、Binder Server 处于不同的进程,他们三个都在用户空间,而 Binder 驱动在内核空间。

  1. Server进程通过Binder驱动,在ServiceManager( 映射关系表 )注册。
  2. Client进程通过Binder驱动,在ServiceManager( 映射关系表 )查找到相应的Server进程代理对象
  3. Client进程通过Binder驱动再与Server进程通信。

Linux 自 带 多 种 进 程 通 信 方 式 , 为 什 么 Android 都没采用二偏偏使用 Binder 通信

Linux 现有的所有进程间 IPC

  1. 管道

  1. 消息队列

缺点: 信息复制两次,额外的 CPU 消耗;不合适频繁或信息量大。

  1. 共享内存

优点:无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快。
缺点: 通信需要设计复杂的机制保证各个进程通讯有效性。进程间的同步 问题操作系统无法实现,必须各进程利用同步工具解决; 安全问题比较 突出,如果 Android 采用 Binder 无异于将每个 App 放在一个内存中,这 样是非常不安全的

  1. 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信
  2. 信号量 ,常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访

问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

  1. 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死

某个进程等;

5 个角度来展开对 Binder 的分析

  1. 从性能的角度

数据拷贝次数:Binder 数据拷贝只需要一次,而管道、消息队列、Socket 都需要 2 次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder 性能仅次于共享内存。

  1. 从稳定性的角度

Binder 是基于 C/S 架构的。

  1. 从安全的角度

传统 Linux IPC 的接收方无法获得对方进程可靠的 UID/PID,从而无法鉴别对方身份。只能由用户在数据包里填入 UID/PID;另外,可靠的身份标记只有由 IPC机制本身在内核中添加。其次传统 IPC 访问接入点是开放的,无法建立私有通道。从安全角度,Binder 的安全性更高。

  1. 从语言层面的角度

大家多知道 Linux 是基于 C 语言(面向过程的语言),而 Android 是基于 Java 语言(面向对象的语句),而对于 Binder 恰恰也符合面向对 象的思想,将进程间通信转化为通过对某个 Binder 对象的引用调用该对象的方 法,而其独特之处在于 Binder 对象是一个可以跨进程引用的对象,它的实体位 于一个进程中,而它的引用却遍布于系统的各个进程之中。可以从一个进程传给 其它进程,让大家都能访问同一 Server,就像将一个对象或引用赋值给另一个引 用一样。Binder 模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于 同一个面向对象的程序之中。从语言层面,Binder 更适合基于面向对象语言的 Android 系统,对于 Linux 系统可能会有点“水土不服”。 另外,Binder 是为 Android 这类系统而生,而并非 Linux 社区没有想到 Binder IPC 机制的存在,对于 Linux 社区的广大开发人员,我还是表示深深佩服,让世 界有了如此精湛而美妙的开源系统。也并非 Linux 现有的 IPC 机制不够好,相 反地,经过这么多优秀工程师的不断打磨,依然非常优秀,每种 Linux 的 IPC 机制都有存在的价值,同时在 Android 系统中也依然采用了大量 Linux 现有的 IPC 机制,根据每类 IPC 的原理特性,因时制宜,不同场景特性往往会采用其下 最适宜的。比如在 Android OS 中的 Zygote 进程的 IPC 采用的是 Socket(套 接字)机制,Android 中的 Kill Process 采用的 signa(l 信号)机制等等。而 Binder 更多则用在 system_server 进程与上层 App 层的 IPC 交互。

  1. 从公司战略的角度

总所周知,Linux 内核是开源的系统,所开放源代码许可协议 GPL 保护,该协议具有“病毒式感染的能力,怎么理解这句话呢?受 GPL 保护的 Linux Kernel 是运行在内核空间,对于上层的任何类库、服务、应用等运行在用户空间,一旦进行 SysCall(系统调用),调用到底层 Kernel,那么也必须遵循 GPL 协议。 而 Android 之父 Andy Rubin 对于 GPL 显然是不能接受的,为此,Google 巧妙 地将 GPL 协议控制在内核空间,将用户空间的协议采用 Apache-2.0 协议(允许 基于 Android 的开发商不向社区反馈源码),同时在 GPL 协议与 Apache-2.0 之 间的 Lib 库中采用 BSD 证授权方法,有效隔断了 GPL 的传染性,仍有较大争议, 但至少目前缓解 Android,让 GPL 止步于内核空间,这是 Google 在 GPL Linux 下 开源与商业化共存的一个成功典范。

Binder 的今世前缘,Binder 是基于开源的 OpenBinder 实现的,OpenBinder 是一个开源的系统 IPC 机制,最初是由 Be Inc.开发,接着由 Palm, Inc.公司负责开发,现在 OpenBinder 的作者在 Google 工作,既然作者在 Google 公司,在用户空间采用 Binder 作为 核心的 IPC 机制,再用 Apache-2.0 协议保护,自然而然是没什么问题,减少法 律风险,以及对开发成本也大有裨益的,那么从公司战略角度,Binder 也是不错 的选择。 另外,再说一点关于 OpenBinder,在 2015 年 OpenBinder 以及合入到 Linux Kernel 主线 3.19 版本,这也算是 Google 对 Linux 的一点回馈吧 。