美文网首页
Android Binder机制

Android Binder机制

作者: 以帅服人的珂哥 | 来源:发表于2019-02-27 02:01 被阅读0次

    参考感谢https://www.jianshu.com/p/4ee3fd07da14

    一、什么是 Binder

    1. 从模型、机制的角度讲:
      BIndier 是Android 中跨进程通信的一种方式。
    2. 从模型的结构、组成来说
      BIndier 是一种虚拟的物理设备驱动。连接 server 进程、client 进程、与 ServiceManager 进程。
    3. 从 Android 的代码角度实现来说
      BIndier 是一个 类 继承了 IBinder 接口,是 BIndier 机制模型的 代码实现。

    二、Linux 进程模型

    1、模型

    进程模型
    1. 每个进程分为 用户控件与内核空间,二者是隔离的,二者之间数据传递要通过系统的 copy_from_user()与 copy_to_user()拷贝数据。
    2. 不同进程之间用户控件的数据是不可共享的,而内核空间的数据是所有进程共享的。
    3. android中为了保证安全性与独立性,一个进程不能操作或访问另一个进程。即进程间是相互独立的、隔离的。

    2、 传统的进程间通信

    由上信息,可想到传统的进程通信原理:

    可通过copy_from_user()与 copy_to_user()以内核空间作为中介 进行数据传递。

    但缺点显而易见:

    • 数据需要两次拷贝,效率低下
    • 接收方进程不知道发来的数据需要多大空间,所以要么开辟尽量大的内存,要么先行传递数据空间大小信息,前者浪费空间,后者浪费时间。

    而 通过Binder机制进行 进程间通信,数据只需一次拷贝,同时负责创建接收区缓存空间,与管理接收方缓存的工作。

    三、Binder 原理

    1、Binder 进程间通信模型

    采用 Client — Server 模型。


    Binder C/S模型

    角色介绍:
    1、 Client 进程 ,使用服务的进程。
    2、server 进程, 提供服务的进程。
    3、 ServerManager, 提供server 进程 Binder 实体的注册,建立该 Binder 的引用,再将字符串形式的 Binder 名字与 Binder 引用维护到一张表中。client 进程则可以通过 所需服务Binder的字符串名字 查询到 Binder 的引用,进而进行进程间通信。
    4、 binder 驱动,一种虚拟的物理设备,是 client 、server、与 serviceManager 的桥梁。作用:

    • 传递服务进程消息
    • 建立内存映射(此处即为 Binder 进行IPC数据只需一次拷贝的秘密)
    • 实现线程控制

    2、通信的具体步骤

    1. server注册服务
      1. sever 进程想 Binder驱动 发起注册服务请求。
      2. Bindier 驱动 向 ServiceManager 转发请求。
      3. ServiceManager 收到请求,注册该服务。
    2. client获取服务
      1. client进程 向 Binder 驱动发起获取服务请求。传递字符串服务名。
      2. Binder 驱动 转发请求给 ServiceManager
      3. ServiceManager 查找到对应的服务信息 通过 Binder 驱动将服务信息转发给 client。

    至此client 进程与 server 进程已经建立了连接。

    1. 调用服务
      1. Binder驱动为通信做准备
        。创建一块接收缓冲区
        。通过 ServiceManager 查到 Server 信息,调用系统的 mmap()函数建立 server进程的
        用户空间——内核空间——接收缓冲区 映射关系。

      2. client 进程将参赛数据发送到 server 进程
        。client 进程通过copy_from_user()函数 像内核空间写入数据,并挂起当前线程。
        由于存在映射关系,故相当于数据已经发送到了server 进程的 用户空间。
        。Binder 驱动通知 server 进程执行解包

      3. server 进程根据 client 的请求 调用目标方法。
        。收到 Binder 驱动的通知后 从线程池取出线程,并执行解包、调用目标方法操作
        。将执行结果写入自己共享内存中。

      4. 将结果返回给 client
        。server 将最终执行结果写入存在映射的用户空间中,由于内存映射关系,想当于 结果传递给了client
        。Binder 驱动 通知 client 接收结果,唤醒 client 挂起的线程
        。client 通过copy_to_user()将数据拷贝至自己的进程的用户空间。


        示意图

    至此通信结束

    优点:

    每次单向通信只需一次内存拷贝,传输效率高。
    为接收进程分配了不确定大小的接受缓冲区

    三、一些疑问点

    1、为什么 Client 进程、Server 进程、ServiceManager 进程之间的交互都必须通过 Binder 驱动?

    参照上文中 Linux 进程模型

    1. Client进程、Server进程 & Service Manager进程属于进程空间的用户空间,不可进行进程间交互。
    2. Binder驱动 属于 进程空间的 内核空间,可进行进程间 & 进程内交互。
    2、ServiceManager是参与 BInder 机制的,但是为什么与ServiceManager 进程通信也是用的 Binder 机制?

    Binder驱动 & Service Manager进程 属于 Android基础架构(即系统已经实现好了);而Client 进程 和 Server 进程 属于Android应用层(需要开发者自己实现)

    相关文章

      网友评论

          本文标题:Android Binder机制

          本文链接:https://www.haomeiwen.com/subject/dmqtuqtx.html