Android-Binder基本原理

一、进程角度看IPC机制

在Android系统中,每个进程只能运行在自己所拥有的虚拟地址空间。例如,一个4GB的虚拟地址空间,包含3GB的用户空间和1GB的内核空间,内核空间的大小可以通过参数配置进行调整。两个进程之间的用户空间是彼此独立的,但内核空间是可共享的。Server 进程与 Client 进程之间就是利用共享的内核空间进行通信的,Server 端与 Client 端主要使用 ioctl 等方法跟内核空间的驱动进行交互。

 二、Binder原理

2.1 使用Binder的优点

在传统的Linux中存在多种IPC的方式,例如SystemV、管道、Socket等。但是Android系统没有大量采用原有的技术方式,而是开发了 Binder 并在系统中大量使用。主要原因有如下几点:

1.性能方面

  • 跨进程通讯中,只有socket支持Client-Server的通信方式,但是socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。
  • 消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。
  • 共享内存虽然无需拷贝,但控制复杂,难以使用。
  • 广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对于传统的Socket方式,有更高的性能,它只需要1次数据拷贝。

2.安全方面

  • 首先传统IPC的接收方无法获得对方进程可靠的UID和PID(用户ID进程ID),从而无法鉴别对方身份。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID和PID,但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。比如命名管道的名称,systemV的键值,socket的ip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。

3.是否易用

  • Binder使用面向对象的设计,基于C/S架构,进行一次远程调用和直接调用本地调用一样,使用方便。并且Binder驱动通过引用计数法实现了管理跨进程传递的代理对象的生命周期。

基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。Binder基于Client-Server通信模式,传输过程只需一次拷贝,为发送方添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。

2.2 Binder架构

Binder采用 C/S 架构,其中的角色主要包括Client、Server、ServiceManager和Binder驱动。

  • Client进程:使用服务的进程。
  • Server进程:提供服务的进程。
  • ServiceManager进程:ServiceManager的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用。
  • Binder驱动:驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。

系统首次启动 ServiceManager 后,当 Client 和 Server 通信时都需要先获取 ServiceManager 接口。因此无论是注册服务还是获取服务,都需要 ServiceManager,需要主要的是此处的 ServiceManager 是指 Native 层的 ServiceManager(C++)。

1.注册服务:Server 进程要先注册 Service 到 ServiceManager。该过程,Server是客户端,ServiceManager 是服务端。

2.获取服务:Client 进程使用某个 Service 前,需要先向 ServiceManager 中获取相应的 Service。该过程,Client 是客户端,ServiceManager 是服务端。

3.使用服务:Client 根据获得的 Service 信息建立与 Service 所在的 Server 进程通信的通路,之后就可以与 Service 交互了。该过程:Client 是客户端,Server 是服务端。

2.3 Binder的工作流程

  1. Server 进程向 ServiceManager 注册,告诉 ServiceManager 我是谁,我有什么,我能做什么。假如 Server 进程有一个 computer 对象,这个对象有个add方法。这时映射关系表就生成了。
  2. Client 进程向 ServiceManager 查询,我要调用 Server 进程的 computer 对象的 add 方法,这时候 Binder 驱动就开始发挥他的作用了。当向 ServiceManager 查询完毕,Binder 驱动将 computer 对象转换成了 computerProxy 对象,并转发给了 Client 进程,因此,Client 进程拿到的并不是真实的 computer 对象,而是一个代理对象,即 computerProxy 对象。很容易理解这个 computerProxy 对象也是有 add 方法。
  3. 当 Client 进程调用 add 方法,这个消息发送给 Binder 驱动,这时驱动发现,原来是computerProxy,那么 Client 进程应该是需要调用 computer 对象的 add 方法的,这时驱动通知 Server 进程,调用你的 computer 对象的 add 方法,将结果给我。然后 Server 进程就将计算结果发送给驱动,驱动再转发给 Client 进程,最终 Client 进程拿到了计算结果。

2.4 Binder的线程管理

  • 每个 Binder 的 Server 进程会创建很多线程来处理 Binder 请求,而真正管理这些线程并不是由这个 Server 端来管理的,而是由 Binder 驱动进行管理的。
  • 一个进程的 Binder 线程数默认最大是 16,超过的请求会被阻塞等待空闲的 Binder 线程。理解这一点的话,你做进程间通信时处理并发问题就会有一个底,比如使用 ContentProvider 时(又一个使用 Binder 机制的组件),你就很清楚它的CRUD(创建、检索、更新和删除)方法只能同时有 16 个线程在跑。
  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binderAndroidbinde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个层次水平的android开发者。1、灵活使用binder跨进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行跨进程通信,及内存等拷贝方式数据等4、对binder从上层的java app端一直到最底层的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种跨进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向跨进程通信10、使用socket实现一个可以让app执行shell命令的程序
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A-sL1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值