:简介)
源码基于Android R0. 前言在Linux 系统中现有的进程间通信IPC方式管道(PIPE)在创建时分配一个page大小的内存缓存区大小比较有限命名管道(FIFO)考虑 PIPE_BUF 和原子操作消息队列信息复制两次额外的CPU消耗不合适频繁或信息量大的通信共享内存无须复制共享缓冲区直接付附加到进程虚拟地址空间速度快但进程间的同步问题操作系统无法实现必须各进程利用同步工具解决套接字作为更通用的接口传输效率低主要用于不同机器或跨网络的通信信号量常作为一种锁机制防止某进程正在访问共享资源时其他进程也访问该资源。因此主要作为进程间以及同一进程内不同线程之间的同步手段信号不适用于信息交换更适用于进程中断控制比如非法内存访问杀死某个进程等0.1 使用Binder 原因0.1.1 性能Socket 作为一款通用接口其传输效率低开销大主要用在跨网络的进程间通信和本机上进程间的低速通信。消息队列和管道采用存储-转发方式即数据先从发送方缓存区拷贝到内核开辟的缓存区中然后再从内核缓存区拷贝到接收方缓存区至少有两次拷贝过程。共享内存虽然无需拷贝但控制复杂难以使用。Binder 只需要一次数据拷贝性能上仅次于共享内存。0.1.2 稳定性Binder 基于 C/S 架构客户端Client有什么需求就丢给服务端Server去完成架构清晰、职责明确又相互独立自然稳定性更好。共享内存虽然无需拷贝但是控制负责难以使用。从稳定性的角度讲Binder 机制是优于内存共享的。0.1.3 安全性Android 为每个安装好的 APP 分配了自己的 UID故而进程的 UID 是鉴别进程身份的重要标志。传统的 IPC 只能由用户在数据包中填入 UID/PID但这样不可靠容易被恶意程序利用。可靠的身份标识只有由 IPC 机制在内核中添加。其次传统的 IPC 访问接入点是开放的只要知道这些接入点的程序都可以和对端建立连接不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。同时 Binder 既支持实名 Binder又支持匿名 Binder安全性高。2. Binder 划分在Android 8.0 之前Binder机制比较简单只有一个驱动设备/dev/binder,一个守护进行/system/bin/servicemanager一个binder库/system/lib64/libbinder.so.在Android 8.0开始Android引入了Treble的机制为了方便Android系统的快速移植、升级提升系统稳定性Binder机制被拓展成了/dev/binder,/dev/hwbinder/dev/vndbinder。我们原先使用的/dev/binder成为框架进程的专有节点这意味着供应商进程无法再访问此节点。供应商进程可以访问 /dev/hwbinder但必须将其 AIDL 接口转为使用 HIDL。对于想要继续在供应商进程之间使用 AIDL 接口的供应商需要使用 /dev/vndbinder而非 /dev/binder。Android8.0 及之后的Binder域如下图所示3. 三种 binder 介绍3.1 vndbinder 和 bindervnbinder 和binder 使用的是一个ServiceManager 和libbinder只不过在选择的时候会区分open /dev/binder 还是/dev/vnbinderframeworks/native/cmds/servicemanager/main.cpp int main(int argc, char** argv) { if (argc 2) { LOG(FATAL) usage: argv[0] [binder driver]; } const char* driver argc 2 ? argv[1] : /dev/binder; spProcessState ps ProcessState::initWithDriver(driver); ps-setThreadPoolMaxThreadCount(0); ps-setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY); spServiceManager manager new ServiceManager(std::make_uniqueAccess()); if (!manager-addService(manager, manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { LOG(ERROR) Could not self register servicemanager; } .. }代码中根据参数选择性的将driver 传入进行open详细看ProcessState::initWithDriver() 函数。通常供应商进程不直接打开 Binder 驱动程序而是链接到打开 Binder 驱动程序的 libbinder 用户空间库。为 ::android::ProcessState() 添加方法可为 libbinder 选择 Binder 驱动程序。供应商进程应该在调用 ProcessState、IPCThreadState 或发出任何普通 Binder 调用之前调用此方法。要使用该方法请在供应商进程客户端和服务器的 main() 后放置以下调用ProcessState::initWithDriver(/dev/vndbinder);dev/binder和dev/vndbinder无法在一个进程中同时使用binder和vndbiner 的机制共用一套libbinder因此两者使用时每次只能指定一个设备节点不能同时使用。3.2 hwbinderhwbinder 独立于binder和vndbinder拥有独立的驱动设备/dev/hwbinder独立的hwservicemanager (system/hwservicemanager/ 目录) 和独立的binder 库libhwbinder (system/libhwbinder/ 目录)。android 8.0 以后采用了treble 的架构framework 和HAL 是独立的在不同的 fw 和 HAL 进程中进程间通信使用的是 HIDL 语言而不在使用 AIDL 语言因此使用了不同的 binder 驱动设备3.3 binder 库的变化bindervndbinderhwbinderlib binder 位置frameworks/native/libs/binderframeworks/native/libs/bindersystem/libhwbinderservice manager 位置frameworks/native/cmds/servicemanagerframeworks/native/cmds/servicemanagersystem/hwservicemanager