Android Binder

一、简介:

  Binder是跨进程内存访问,是Android中使用最广泛的IPC机制。

  Binder由以下几部分组成:

    • Binder驱动 
    • Binder Manager
    • Binder Client
    • Binder Service

  对照TCP/IP中Client与Server服务连接过程:

    • Binder驱动 -- 路由器(Router)
    • Binder Manager -- DNS 服务器
    • Binder Client -- Client
    • Binder Server -- Server

  让Client与Server连接需要以下几个步骤,以请求baidu.com为例:

  1. 首先,Cleint向DNS域名服务器发起请求,请求查询指定baidu.com的IP地址,并返回给Client。
  2. 然后,Client通过从DNS获取的IP地址,向baidu.com发起连接。在整个过程中都没提起Router的作用,它担负的责任是将数据包投递到用户指定的目标IP中,即Router是整个通信结构的基础。

二、进程间数据传递载体 -- Parcel

  假如进程间传递的数据是一个int类型数据,只要不断复制直到目标进程即可。那么,进程间传递的数据是一个对象,这时该怎么做?从所周知,在同一进程中传递数据是通过对象引用来做的,因而本质上传递的是内存的地址。由于采用了虚拟内存机制,两个进程都拥有自己独立的内存空间,跨进程传递的内存地址是无效的。

  进程间传递数据是IBinder中重要一环,在Android中负责进程间传递数据的载体是Parcel,中文翻译是打包。

  Parcel是一种载体,用于承载通过IBinder发送的数据相关信息(包括数据和对象引用)。在跨进程中传递内存地址这种方式是无效的,那么,将进程A中的对象的相关数据信息打包,传递到进程B中,再由进程B将数据“复现”。而Parcel就有将数据打包和重组的能力。

三、Binder驱动

  Android系统基于Linux内核,因而它所依赖的Binder驱动也是一个标准Linux驱动。Binder Driver会将自己注册成一个misc device,并向上层提供一个/dev/binder节点,值得一提的是Binder节点并对应真实的硬件设备。Binder驱动运行于内核态,并提供oper()、ioctl()、mmap()等文件操作函数。

  PS:个人理解,就是Binder驱动通过文件操作函数,在物理内存中申请一块区域,并将这块物理内存映射到虚拟内存中,并且这个物理内存是一块共享内存区,这样就通过一次数据复制就做到了跨进程的数据传递。因为,其它进程也可以访问这块共享的物理内存。

四、“DNS”服务器 -- Service Manager(Binder Manager [Binder Server])  

  Service Manager的功能类拟于互联网中的DNS服务器,IP地址为“0”。和DNS本身也是服务器一样,Service Manager也是一个标准的Binder Server。在整个Android系统中只允许有一个Binder的Service Manager存在,因而在后面还有人调用binder_become_context_manager(...)函数就会调用失败。在Android系统启动时,Service Manager就会被启动。

  Service Manager在启动时,做了以下几件事:

  1. 打开Binder设备(/dev/binder),做好初始化。

  2. 将自己设置为Binder的“大管家”,即Service Manager。

  3. 进入主循环,等待客户端消息。

  Service Manager在完成启动后,一切准备就绪,在消息的处理上和典型的基于事件驱动的程序循环框架类似:

    • 从消息队列中读取消息。
    • 如果消息是“退出命令”,则马上结束循环;如果消息是空,则继续读取消息或者等待一段时间后再读取消息;如果消息不是空并且消息不是退出命令,则根据消息的具体情况处理。
    • 如此循环往复直到退出。

  不过Service Manager中没有消息队列,它的“消息”或者称“命令”是从Binder驱动中获取的。

五、Binder Client

 

PS:Binder进阶

posted @ 2021-09-04 16:15  naray  阅读(212)  评论(0编辑  收藏  举报