简单理解Binder机制的原理和从AIDL层解析使用方法

推荐参考资料:
如果不想看我下面的一堆文字,建议顺序依次看一下下面的3篇文章,很有收获

https://www.jianshu.com/p/4920c7781afe?from=jiantop.com

http://www.cnblogs.com/zc9527/p/5638688.html

https://www.cnblogs.com/itgungnir/p/6640120.html

以下内容做记录帮助记忆吧

1.什么是Binder

Binder机制具体有两层含义:
  • Binder是一种跨进程通信(IPC,Inter-Process Communication)的手段;
  • Binder是一种远程过程调用(RPC,Remote Procedure Call)的手段。

Binder是安卓进程间通信机制,linux中没有时android中特有的。为什么要进程间通信呢?当一个进程想为其它进程提供服务时,或其他进程想访问你提供的服务,就需要通过进程间通信的方式来实现了。

打个比方:

我们有一个APP1,里面有个service可以提供很牛逼的测量计算功能,而这个功能又很复杂很难实现。
当另外一个APP2想使用APP1里面的service的测量计算功能,由于不同的APP运行在不同的进程中,
所以,APP2是无法直接使用APP1里面的service的测量计算功能。由于跨越了进程,只能通过进程间通信机制来完成。

2.为什么要使用Binder?

1.历史原因

Binder最早并不是为Android系统而设计的,最开始有一个OpenBinder的东西,用在一个叫做Palm Cobaltw的为内核操作系统上。后来,Palm Cobaltw移植到了Linux系统上,OpenBinder也跟着移植了过来。Google在组建Android开发团队的时候,聘请了一位叫做Dianne Hackborn的工程师,而他就是OpenBinder的核心人员。后面在做android进程间通信时,发现binder很合适,就理所当然的在android系统上使用了Binder。

2.性能方面
在移动设备上(性能受限制的设备,比如要省电),广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对出传统的Socket方式,更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。

3.安全方面
传统的进程通信方式对于通信双方的身份并没有做出严格的验证,比如Socket通信ip地址是客户端手动填入,很容易进行伪造,而Binder机制从协议本身就支持对通信双方做身份校检,因而大大提升了安全性。

3.Binder有哪些组成部分?

一个Binder系统由四部分组成:Binder客户端、Binder服务端、Binder驱动、服务登记查询模块

  1. Binder客户端:想要使用服务的进程

  2. Binder服务端:实际提供服务的进程

  3. Binder驱动
    我们在客户端先通过Binder拿到一个服务端进程中的一个对象的引用Proxy,通过这个引用,直接调用对象的方法获取结果。在这个引用对象执行方法时,它是先将方法调用的请求传给binder驱动;然后binder驱动再将请求传给服务端进程代理Stub;服务端进程收到请求后,调用服务端“真正”的对象来执行所调用的方法;得出结果后,将结果发给binder驱动;binder驱动再将结果发给我们的客户端;最终,我们在客户端进程的调用就有了返回值。Binder驱动,相当于一个中转者的角色。通过这个中转者的帮忙,我们就可以调用其它进程中的对象。

  4. 服务登记查询模块
    我们调用其它进程里面的对象时,首先要获取这个对象。这个对象其实代表了另外一个进程能给我们提供什么样的服务(再直接一点,就是:对象中有哪些方法可以让客户端进程调用)。首先服务端进程要在某个地方注册登记一下,告诉系统我有个对象可以公开给其它进程来提供服务。当客户端进程需要这个服务时,就去这个登记的地方通过查询来找到这个对象。

4.Binder工作流程

假设:客户端的程序Client运行在进程A中,服务端的程序Server运行在进程B中。

  • 由于进程的隔离性,Client不能读写Server中的内容,但内核可以,而Binder驱动就是运行在内核态,因此Binder驱动帮我们进行请求的中转。

  • 有了Binder驱动,Client和Server之间就可以打交道了,但是为了实现功能的单一性,我们为Client和Server分别设置一个代理:Client的代理Proxy和Server的代理Stub。这样,由进程A中的Proxy和进程B中的Stub通过Binder驱动进行数据交流,Server和Client直接调用Stub和Proxy的接口返回数据即可。

  • 此时,Client直接调用Proxy这个聚合了Binder的类,我们可以使用一系列的Manager来屏蔽掉Binder的实现细节,Client直接调用Manager中的方法获取数据,这样做的好处是Client不需要知道Binder具体怎么工作。

  • 最后还有一个问题,就是Client想要获得的服务多种多样,那么它是怎么获取Proxy或Manager的呢?答案是通过Service Manager进程来获取的。Service Manager总是第一个启动的服务,其他服务端进程启动后,可以在Service Manager中注册,这样Client就可以通过Service Manager来获取服务器的服务列表,进而选择具体调用的服务器进程方法。

  • 上面的叙述总结为如下图所示的工作流程图:

在这里插入图片描述


----------------------------------分割线----------------------------
对上图进行简化大概如下图:.

在这里插入图片描述

  1. client通过获得一个server的代理接口,对server进行调用。
  2. 代理接口中定义的方法与server中定义的方法时一一对应的。
  3. client调用某个代理接口中的方法时,代理接口的方法会将client传递的参数打包成Parcel对象。
  4. 代理接口将Parcel发送给内核中的binder driver。
  5. server会读取binder driver中的请求数据,如果是发送给自己的,解包Parcel对象,处理并将结果返回。
    整个的调用过程是一个同步过程,在server处理的时候,client会block住。因此client调用过程不应在主线程。

对AIDL对Binder的使用推荐参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值