Binder机制
目录
- Binder是什么
- Binder通信机制
- Binder驱动
- Service Manager
- Binder机制跨进程通信流程
- 总结
先给出Android中的Binder的工作机制图
我们在上一篇文章讲解了AIDL生成的Java文件,我们知道AIDL的实现是依赖与Binder机制的,此篇就简单讲解Binder机制。
Binder是什么
要说Binder就不得不提到Linux,毕竟Android底层是Linux,但是为什么Android并没有用Linux常用的IPC机制,而是新创建了快速的、轻量级的、更适用小型设备的Binder机制,因为Linux的IPC机制无法做到足够轻量,较Binder会产生更多的性能消耗,所以Binder就在这中环境下应运而生。
借用《Android 开发艺术探索》对Binder的概括
- 从代码角度来看,Binder是一个实现了IBinder接口的类
- 从来源看,Binder来自于OpenBinder,是Android IPC机制中的一种,Binder还可以理解成一个虚拟物理设备,设备驱动是dev/binder;
- 从Framework层看,Binder是Service Manager连接各种Manager(ActivityManager,PackageManager…)和相应Service (ActivityManagerService, PackageManagerService…)的桥梁;
- 从客户端看,Binder是客户端服务器通讯的媒介
Binder通信机制
一个完整的Binder机制中有四个元素组成,
- client,客户端
- Server,服务端
- Binder device,Binder驱动,Binder机制的核心
- Service Manager,服务管理类,内部持有所有的服务IBinder服务
Binder驱动
驱动程序一般指的是设备驱动程序(Device Driver),是一种可以使操作系统和硬件通信的特殊程序。类似硬件的接口,操作系统只有通过这个接口才能与硬件通信。
在Linux系统中,有用户空间和内核空间两种内存空间
- 用户空间:应用程序运行的空间
- 内核空间:系统内核和驱动运行的空间
用户空间不能直接访问内核空间,需要通过System Call Interface(系统调用接口),内核对这个接口进行管理,防止用户程序对系统资源的越权访问,保障了系统的安全和稳定。同样的进程之间也不能直接访问需要经过内核空间进行中转。
在一个跨进程访问种Binder驱动做了下面两件事,实现数据的中转。
- Client将数据从用户空间拷贝到内核空间
- Binder驱动将拷贝到内核空间的数据拷贝到Server所在的用户空间
这就是Binder机制的根本原理
Service Manager
Server的管理类,负责对Server端的管理,持有所有Server端,类似AMS
Binder机制跨进程通信流程
直接上图
Binder实体
- 每个Server都可以看成一个Binder实体,持有Server和ServiceManager的信息
- 驱动通过Binder实体中保存的Server信息,就可以找到在用户空间中对应的Server
Binder引用
- Binder实体的引用,是内核中Binder_ref的实例,在内核中通过Biner引用就可以找到对应的Binder实体,类似C的指针都是指向某一个内存空间
Binder跨进程通信步骤:
- 初始化
- ServiceManager初始化,ServiceManager会和Binder驱动通信,将自己的引用给ServiceManager
- Binder驱动利用ServiceManager的引用新建ServiceManager实体
- 注册
- Server启动时向驱动发起注册请求,驱动为其创建Binder实体
- 驱动通知ServiceManager进行注册,如果ServiceManager的引用表中没有此Binder引用,就将其名称和Binder引用添加到引用表,此处的名称就是Binder.attachInterface中传入的descriptor
- 获取
- Client请求驱动获取某一名称的Binder引用,驱动将请求交给ServiceManager处理
- ServiceManager根据传入的名称查询引用表,如果有对应名称的Binder引用就通过驱动反馈给Client
- Client根据反馈的Binder引用,创建对应的远程服务代理
- 发送
- Client调用远程服务代理,远程服务代理与驱动Server进行通信
- 驱动通过远程服务代理中已有的Server的Binder引用找到对应的Server,将Client的请求发送给Server
总结
简单来说,用户空间的每一个进程对应一个JVM,而每一个JVM都会单独的开辟内存空间,两个JVM之间是不能直接进行通信的,必须通过内核进行中转,Binder驱动就是起到这个中转作用,这完全保证了Android的C-S架构,保障了系统安全,当C进行请求时经过Binder驱动,Binder驱动找到对应的S,S处理请求之后通知Binder驱动,Binder驱动将处理结果反馈给C,这就是一次完成的请求响应过程。
此篇只是简单的阐述了一下Binder机制的应用层的原理与逻辑,更深入的内容需要大家共同的深入研究。
最后推荐一下,http://wangkuiwu.github.io/categories/