阅读 508

Android Framework重要服务之Binder(一) 概述

一、什么是Binder

简单地说,Binder是Android平台上的一种跨进程交互技术。该技术最早并不是由Google公司提出的,它的前身是Be Inc公司开发的OpenBinder,而且在Palm中也有应用。后来OpenBinder的作者Dianne Hackborn加入了Google公司,并负责Android平台的开发工作,所以把这项技术也带进了Android。

在Android的中,我们知道每个应用都是一个独立的进程,有一个独立的虚拟机,应用和应用之间的内存是不能共享数据的,但是我们用到Activity、Service、Context、provider等功能时恰恰需要大量的数据传输,这种进程间通信的机制被称为:IPC(Inter-Process Communication)。

在Android中常常使用的进程间通信有 共享内存、管道、信号处理、socket、Binder等。每个通信方式都有各自的优缺点,Android通常在合适的地方使用合适的通信方式,比如:内核和用户空间常用的是共享内存机制,一些低数据传输使用socket处理,应用进程之间传输使用Binder机制。
本章将概述Binder的机制原理。

二、Binder作为Android IPC的优势

Linux进程间通信有很多方式,这里大概总结一下这些进程间通信方式的特点:

方式特点
管道在创建时分配一个page大小的内存,缓存区大小比较有限;
消息队列信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
共享内存无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
套接字作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信;
信号量常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
信号不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;

从上表可以看出,Android之所以选择Binder作为通过IPC方式主要基于一下几个方面的优点:

  • 性能角度(数据拷贝次数):共享内存(0)< Binder(1)< 管道/消息队列/Socket(2)

  • 稳定性角度:Binder是基于C/S架构的,结构清晰,两端相对独立。而共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题;从这稳定性角度看,Binder架构优越于共享内存。

  • 安全性角度:传统Linux IPC无任何保护措施,完全由上层协议来确保,另外无法鉴别对方进程身份。 Binder机制对于通信双方的身份是内核进行校检支持的,可以获得对方进程可靠的UID/PID,做安全访问控制。

三、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域如下表所示:

IPC域说明
/dev/binder框架/应用之间的IPC,使用AIDL接口
/dev/hwbinder框架/供应商之间的IPC和供应商进程间的IPC,使用HIDL接口
/dev/binder供应商/供应商之间的IPC,使用AIDL接口

四、三种Binder介绍以及之间的联系

1. Binder

在Android 8.0之前,Binder机制比较简单,只有一个Binder。Java层继承Binder,Native C/C++层继承Bbbinder,然后通过servicemanager进程注册实名Binder,然后通过已经创建好的Binder接口传递匿名Binder对象,拿到BinderProxy或者BpBinder以后,就可以Binder通信了。

在Android 8.0后,这个Binder机制继续保留,/dev/binder 设备节点成为框架进程的专有节点,这意味着供应商进程无法再访问此节点。

如果你是系统厂商,在system分区有进程,/dev/biner机制还是可以继续使用,但是你的进程在vendor分区,那只能使用/dev/hwbinder 或者/dev/vndbinder。

Binder机制需要两个进程都同属于System分区。

2. VndBinder

Android8.0 支持供供应商服务使用的新 Binder 域,访问此域需要使用 /dev/vndbinder(而非 /dev/binder)。为了显示 /dev/vndbinder,请确保内核配置项 CONFIG_ANDROID_BINDER_DEVICES 设为 "binder,hwbinder,vndbinder"(这是 Android 通用内核树的默认设置)。vndbinder和binder共用libbinder这个系统库,只是在守护进程和内核空间有一些区别,整体代码流程和使用方式基本一致。

Java层继承Binder,Native C/C++层继承Bbbinder,通过vndservicemanager进程注册实名Binder,然后通过已经创建好的Binder接口传递匿名Binder对象,拿到BinderProxy或者BpBinder以后,就可以Binder通信了。

和Binder的区别,就是device变成了"/dev/vndbinder", 守护进程变成了"vndservicemanager"

通常,供应商进程不直接打开 Binder 驱动程序,而是链接到打开 Binder 驱动程序的 libbinder 用户空间库。为 ::android::ProcessState() 添加方法可为 libbinder 选择 Binder 驱动程序。供应商进程应该在调用 ProcessState,、IPCThreadState 或发出任何普通 Binder 调用之前调用此方法。

binder和vndbiner的机制共用一套libbinder,因此两者使用时,每次只能指定一个设备节点,不能同时使用。

VndBinder机制需要两个进程都同属于Vendor分区。

3. HwBinder

hwbinder和 binder\vndbinder又有所区别,hwbinder是一套全新的流程,有单独的驱动设备"/dev/hwbinder",独立的守护进程"hwservicemanager",独立的SDK-"libhwbinder"。

HwBinder机制可以跨System和Vendor分区使用。


以上三中Binder各自有各自的使用要求,总结起来如下:

IPC域使用要求
Binder供应商无法访问,使用时需要两个进程都同属于System分区
VndBinder需要两个进程都同属于Vendor分区
VndBinder可以跨System和Vendor分区使用

五. 总结

Android引入Treble机制后,扩展了一个vendor分区,为了能够快速的进行升级,做了隔离HAL层的机制,为了System/System、System/Vendor、Vendor/Vendor 之间进行不同的进程间通信,把原有的Binder机制拆分成了Binder、HwBinder、VndBinder。

Binder和VndBinder 共用一套libbinder、servicemanager的代码,使用AIDL接口,两者不能共存。

HwBinder采用了单独的libhwbinder、hwservicemanager的代码,单独管理,使用HIDL接口。

三者之间互不干扰,在方便系统升级的同时,又提升了系统的安全和稳定性。


作者:wise丰
链接:https://juejin.cn/post/7056301924634591240


文章分类
ANDROID
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐