Android Binder机制简述

2023-03-15  本文已影响0人  vb12

Binder机制是Android系统提供的一种高级IPC机制,它使用代理对象、共享内存和序列化等技术,实现了进程间通信和远程调用的功能。它允许在不同进程之间进行数据传输和方法调用,实现了进程间的解耦。在Android系统中,Binder被广泛应用于各种组件之间的通信,例如Activity与Service、Service与Service、应用与系统服务等。

Binder的概念如下:

  1. 驱动层:Binder作为一个设备驱动存在于Linux内核中。当应用程序与Binder对象进行通信时,实际上是在与Binder驱动进行交互。Binder驱动负责管理Binder对象、传输数据以及进程间的上下文切换等工作。设备文件节点通常是 /dev/binder

不过,在某些版本的Android中,您可能会看到其他设备文件节点,如 /dev/hwbinder 和 /dev/vndbinder。这些设备节点都是用于Binder驱动的不同实例,分别用于硬件抽象层(HAL)和供应商模块之间的通信。

  1. 用户空间库:Binder提供了一套C++库和Java库,以方便用户空间的应用程序使用。这些库包括序列化/反序列化数据的工具、用于管理Binder对象的引用计数的工具以及在进程间调用方法时的代理和存根对象等。在Java层,通常使用AIDL(Android Interface Definition Language)来定义跨进程接口。

  2. 代理与存根:Binder机制使用了代理(Proxy)和存根(Stub)对象来实现进程间的方法调用。当一个进程要调用另一个进程中的方法时,它会通过代理对象将方法调用转换为一个Binder事务。然后,这个事务会被发送到接收进程,由存根对象解析并执行对应的方法。最后,存根对象将结果返回给代理对象,完成整个跨进程调用。

  3. 序列化与反序列化:在进程间传输数据时,需要将数据序列化为字节流,以便在不同进程之间进行传输。在接收进程中,数据会被反序列化为原始格式。Binder提供了一套序列化和反序列化的工具(如Parcel类),用于在进程间传输数据。

  4. 引用计数与死亡通知:Binder机制通过引用计数来管理Binder对象的生命周期。当一个进程获得了另一个进程的Binder对象引用时,引用计数会增加。当引用计数减少到零时,Binder对象会被销毁。另外,Binder还支持死亡通知机制,允许一个进程监听另一个进程的Binder对象死亡事件。

实现原理

Binder IPC(进程间通信)机制在数据传输过程中使用了一种称为"引用计数的内存映射"(reference-counted memory mapping)技术。这种技术通过共享内存来减少数据在发送方和接收方之间的复制操作。

在Binder IPC传输过程中,以下步骤涉及到引用计数的内存映射技术:

  1. 发送方进程(客户端)将要传输的数据写入其本地内存。这些数据可能包括原始数据、文件描述符、Binder对象等。
  2. Binder驱动程序在发送方进程和接收方进程(服务端)之间建立一块共享内存区域。这个共享内存区域的引用计数被设置为1。
  3. 发送方进程将数据复制到共享内存区域,并将数据的内存地址和大小传递给Binder驱动程序。
  4. Binder驱动程序将共享内存区域的引用计数增加1,然后将共享内存区域的地址和大小传递给接收方进程。
  5. 接收方进程通过映射共享内存区域来访问数据。此时,共享内存区域的引用计数仍为2。
  6. 当发送方和接收方进程都不再需要这些数据时,它们分别告知Binder驱动程序。驱动程序随后将共享内存区域的引用计数减1。当引用计数降至0时,驱动程序释放共享内存区域。

通过这种引用计数的内存映射技术,Binder IPC可以将数据在进程间的复制操作降至最低,从而提高IPC性能。然而,这种方法并不适用于所有场景。在某些情况下,例如当数据量很小或者不同安全上下文之间的通信时,Binder仍然可能使用传统的数据复制方法。

ServiceManager

ServiceManager在系统启动过程中的初始化非常重要,因为它是Android系统服务管理的核心组件,需要在其他服务启动之前就准备就绪,以便随后可以注册和查找其他系统服务。

  1. Native层的ServiceManager是在Android系统启动阶段初始化的。在Android系统启动过程中,会执行一个名为init的程序,它负责启动和初始化系统中的各个组件和服务。在init程序执行过程中,会调用ServiceManager的main函数,从而启动并初始化Native层的ServiceManager。这样,ServiceManager就可以接收和处理来自其他进程的服务注册和查询请求。

  2. Java层的ServiceManager(位于Java层):它是一个Java类,提供了在Java层注册和获取系统服务的功能。它通过JNI(Java Native Interface)与Native层的ServiceManager进行通信,从而实现对系统服务的查询和注册。 当Java层的ServiceManager需要注册或查找一个系统服务时,它会通过JNI调用Native层的ServiceManager的相应方法。同样,当Native层的ServiceManager收到服务注册或查询请求时,会在其内部映射表中进行查找或添加相应的服务。

相关

  1. 为何System server请求zygote创建进程时用的是socket通讯而不是binder?
    可能是因为此处socket完全满足需求, 简单又高效, 并不是binder此时不可用. 因为servicemanager先于System server启动了.

  2. binder通讯中存在几次内存复制? 为什么?
    (参考文章)https://zhuanlan.zhihu.com/p/558814995
    https://zhuanlan.zhihu.com/p/532966250

  3. 为什么Intent不能传递大数据?

  1. 相对于其他linux ipc机制, binder有什么优势?
上一篇 下一篇

猜你喜欢

热点阅读