1.什么是Binder机制
Binder机制是Android系统中进程间通讯的一种方式,是Android系统实现IPC机制的重要手段
2.为什么要用Binder框架
众所周知,Android底层是Linux系统,Linux有管道(pipe)、信号量、消息队列、信号、共享内存、套接字(socket)等手段跨进程通信方式。为什么Android机制选择用Binder呢?
1.效率比较高
传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。仅此于共享内存方式,因为共享内存必须利用同步工具来保证进程间的同步问题,操作过于复杂,所以放弃使用。从Android进程架构角度分析:对于消息队列、Socket和管道来说,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到接收方的缓存区,一共两次拷贝。
传统的IPC通信如下图:
传统的IPC通信.png
Binder机制只需要拷贝1次,如下图:
Binder跨进程通信.png
Binder机制之所以一次,主要使用了内存映射
1.首先Binder驱动在内核空间创建一个数据接收缓存区
2.然后在内核空间开辟一块内核缓存区,用于接收用户空间A发送的数据。
3.将内核缓存区和用户空间B的地址映射到同一个接收缓存区。
4.将空间进程A的数据通过copy_from_user() 方法拷贝到内核缓存区。
5.因为内核缓存区到接收进程的用户空间存在映射关系,这样用户空间B就可以拿到用户空间A发送来的数据。
2.稳定性
共享内存的性能优于Binder,但是共享内存需要处理并发同步问题,非常容易出现死锁和资源竞争,稳定性较差。Socket虽然是基于C/S架构的,但是它主要是用于网络间的通信且传输效率较低。Binder基于C/S架构 ,Server端与Client端相对独立,稳定性较好。
3.安全性
传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Binder机制为每个进程分配了UID/PID来作为鉴别身份的标示,并且在Binder通信时会根据UID/PID进行有效性检测,安全性更好。
3.Binder框架中ServiceManager的作用
Binder框架是基于C/S框架,由一系列的组件组成。包括 Client、Server、ServiceManager、Binder驱动,其中 Client、Server、ServiceManager 运行在用户空间,Binder 驱动运行在内核空间。
3.1.ServiceManager的作用
ServiceManager其实只提供查询服务和注册服务的功能。
Binder框架中ServiceManager的作用.png
3.2.ServiceManager的启动
ServiceManager启动涉及到native层,我们做应用开发的只需要知道它在init进程启动之后启动就可以了,它主要是用来管理系统中的service。
3.3.Server注册到ServiceManager
1.首先Server会先向Binder驱动发起注册请求
2.Binder驱动收到请求后将该请求转交给ServiceManager进程。
3.当ServiceManager收到Binder驱动转发的注册请求后,就将该Server的相关信息注册到"Binder引用组成的单链表"中。Server相关信息主要包括两部分:Server对应的服务名 + Server对应的Binder实体的一个Binder引用。
3.4.Client从ServiceManager获取服务Server
1.Client首先向Binder驱动发起获取服务的请求。
2.Binder驱动收到Client请求后将该请求转发给ServiceManager进程。
3.ServiceManager收到Binder驱动转发的Client请求后,会从"Binder引用组成的单链表"中找到要获取的Server相关信息。
4.ServiceManager通过Binder驱动将找到的Server信息反馈给Client。其实就Server对应Binder实体的Binder引用信息。
5.Client接收到该Server对应Binder实体的Binder引用信息后,将根据该Binder引用信息创建一个Server对应的远程服务。其实就是Server的代理对象。通过调用代理对象就可以调用Server的接口了。
3.5.Client与Server进行通信
Client通过保存的一个Server对象的Binder引用,来找到该Binder引用在内核中Binder的实体,然后通过Binder的实体找到Server对象,然后将信息发送给Server。
1.Client将数据写入Parcel对象中
2.调用BinderProxy的transact()方法将数据发送给Binder驱动
3.Binder驱动找到Binder引用对应的Binder实体
4.通过Binder实体找到Server进程,并且通知Server。
5.Server收到Binder驱动的通知后,Server进程通过调用Binder对象onTransact()进行数据解包 & 调用目标方法。
6.Binder驱动根据代理对象原路将结果返回给Client。
其实Binder机制很多知识点,也很深,这里只是大概说了一下
网友评论