Android Binder原理及应用

一、Linux跨进程通信简介

        目前进程间主要通信方式有:

管道

        shell命令中通过|分隔两个命令,这会将前后两个进程的输入输出用一个管道相连,以达到进程间通信的目的

ls -l /etc/ | wc -l183
    本质上是一个文件,前面的进程以写方式打开文件,后面的进程以读方式打开。这样前面写完后面读,于是就实现了通信,但是管道本身并不占用磁盘或者其他外部存储的空间。它占用的是内核内存空间,由用户区空间写入和读取。所以,Linux上的管道就是一个操作方式为文件的内存缓冲区
  • 匿名管道,|的形式,特点是只能在父子进程中使用,不灵活
  • 命名管道,手动创建一个管道类似创建一个文件,一个进程写,一个进程读,会阻塞
  • 2次数据拷贝
消息队列

        MQ 采用双向链表来实现消息队列,该链表是由系统内核维护,每个 MQ 用消息队列描述符(消息队列 ID:qid)来区分,是唯一的;提供一种进程间发送数据块的方法。每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构,避免命名管道的同步和阻塞问题;在进行进程间通信时,一个进程将消息加到 MQ 尾端,另一个进程从消息队列中取消息

  • 2次数据拷贝
信号

        发送信号给进程,多用于消息传递和通知,不适合信息交换

信号量

        常用于一种资源锁机制

        信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有,也就是说信号量是用来调协进程对共享资源的访问的,并不用于进程间通信数据

共享内存

        映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式

  • 效率非常高,当做自己的内存区域,直接内存映射的方式,适合大数据量
  • 共享内存并未提供同步机制,通常需要用其他的机制来同步对共享内存的访问,比如信号量,控制较为复杂
  • 0次数据拷贝
Socket

        多用于不同机器跨网络的通信

  • 性能较差,需要包装数据和解包装,有较大开销
  • 2次数据拷贝

二、Binder简介

Binder优势
  • 性能方面的考虑,只需要1次数据拷贝,统一收口在Binder驱动

  • 稳定性,基于C/S架构,Client端有什么需求,直接发送给Server端去完成,架构清晰明朗,Server端与Client端相对独立,稳定性较好,大大优于共享内存
  • 安全性,传统IPC没有任何安全措施,完全依赖上层协议来确保,而这个是开放的,Client可以伪造用户信息。可靠的身份标记只应该由IPC机制本身在内核中添加,为每个App分配UID,来确定是哪个app
  • 语言的角度,Linux是基于C语言,Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中,操作这个对象就像操作本地对象一样方便

Binder通信模型
  • Client
    Binder代理,位于客户端进程
  • Server
    Binder实体,位于服务端进程
  • ServiceManager  (DNS服务器)
    查找表,独立进程
  • BinderDriver  (路由器)
    运行在内核空间,数据传输的核心通道,负责进程之间 Binder 通信的建立,引用计数等等
ServiceManager
  • 是独立的进程,由linux的祖先init进程启动
  • ServiceManager是一个守护进程,负责管理所有的 Android 系统服务,内部维护一个Map来记录已经注册的所有的service
  • ServiceManager的作用是将字符形式的Binder名字转化成对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用
  • 启动后打开Binder驱动
Binder驱动
  • 实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是一样的
  • 内存物理映射
  • 驱动负责进程之间Binder通信的建立
  • 使用Binder进程间通信时,所有的通信都要通过Binder驱动
实名Binder和匿名Binder
  • 直接注册到ServiceManager的是实名Binder
  • 通过一个实名Binder载体传递过来的Binder是匿名Binder
Binder通信整体流程
  1. Server创建自己的Binder,通过Binder驱动把Binder对象和对应的名字,都注册到ServiceManager
  2. Client发起请求,通过0号引用,先从Binder驱动中获取到ServiceManager。然后从ServiceManager里取ServerBinder,并不会给Client进程返回一个真正的Binder对象,而是返回一个看起来跟Binder一模一样的代理对象BinderProxy
  3. BinderProxy没有实际要用的add方法,只提供一个和Binder驱动交流的入口,它唯一能做的事情就是把参数和任务打包然后交给驱动,然后阻塞等待结果
  4. 驱动收到这个消息,通知Server进程,在Binder线程池调用Binder对象的add方法,然后把结果交给驱动,最后驱动把结果返回给Client进程,阻塞结束

Binder通信的代理模式

ICompute.Stub.asInterface(iBinder)

  • 对于Binder的访问,如果是在同一个进程,那么直接返回原始的Binder实体,Stub
  • 如果在不同进程,那么就给他一个代理对象,Stub.Proxy
  • IBinder

代表一种跨进程的能力,Binder和BinderProxy都实现了这个接口

  • Binder

创建在Server端,代表的其实就是Binder本地对象

  • BinderProxy

Binder本地对象的代理,由Client端引用并使用
唯一的功能就是通过transact把命令(方法名、参数、返回值)传递给驱动

  • Stub

继承了Binder,是真正的服务端Binder实体

实现了ICompute接口,有定义的接口能力

  • Stub.Proxy

是个壳子,代理了Binder代理 BinderProxy

实现了ICompute接口,有定义的接口能力,把命令打包传给BinderProxy,发到Binder驱动

  • IInterface

提供了 ICompute 与最原始的 IBinder 互相转换的能力,asBinder()

Stub 和 Stub.Proxy 都实现了这个接口

Stub返回Binder自己,Stub.Proxy返回BinderProxy,即都是返回真实IBinder对象

三、ActivityManagerService简介

        哈哈,没有很熟,将就看下流程图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值