Binder机制---IPC、RPC的过程

Linux内存空间与Binder Driver

Android是基于Linux操作系统的,所以需要先了解Linux内核的知识。Android进程与Linux进程一样,运行在进程固有的虚拟地址空间中。一个4GB的虚拟地址空间,3GB是用户空间,剩余的1GB是内核空间。

一个拥有独立空间的进程如何向另一个进程传递数据呢?显然要通过两个进程共享的内核空间。从内核的角度看,进程不过是一个作业单位,虽然各个进程的用户空间相对独立,但是运行在内核空间中的任务数据、代码都是彼此共享的。 image.png Linux本身就提供IPC工具,用于两个进程通过内核进行通信。Android中的binder功能更丰富,不仅可以进行IPC通信,还可以用来调用另一个进程的函数,即支持进程之间的RPC操作。 IPC:(Inter Process Communication)跨进程通信
RPC: (Reomote Procedure Call) 远程过程调用

Binder通信的过程中,分为两个进程Client和Service。Client和Service是相对的,谁发送消息,谁就是Client,谁接收消息,谁就是Service

进程之间是如何远程调用函数的呢?

image.png 客户端要通过IPC调用实现Server端foo函数的调用,就需要将Binder IPC数据传递给Server端,传递的过程需要Binder Driver充当中间人,接收来自客户端的IPC数据,而后传递给Server端。 IPC数据包含函数调用相关的内容:服务号、RPC数据和代码、binder协议三部分构成。

  • 服务号(Handle):用来区分不同的服务,Driver层通过handle值确定将ipc数据传递给到哪个服务中,也就是目标服务的编号
  • RPC数据:用来指定指定服务中将调用的函数(包括函数名和参数)
  • Binder协议:用来表示IPC数据的处理方式(我们研究的主要就是BINDRE_WRITE_READ协议,用来传递ipc数据)

image.png 上图为binder中各种协议的作用

image.png 此图为binder数据传递的过程,这里体现了Binder机制的分层管理(服务层、RPC层、IPC层、driver层,下来还会讲解这块),binder分为Native层和Java层,每一层都有相应的分层机制。

Context Manager(ServiceMananger)进程以及注册、检索、调用的过程

在Android系统中,有个一名为Context Manager(ServiceMananger)的特殊进程,它为每个服务分配一个称为Handle的编号,并提供添加、检索等功能,Context Manager自身的的handle为0。上面说到Binder Driver会根据IPC数据中的Handle查找Service,也就是寻址的过程。

注册

为了实现这一过程,Service Server必须先把自身服务注册到Context Mananger中,在注册的过程中,Service Server会想Driver层传递IPC数据,其中就包含RPC代码(ADD_SERVICE,添加服务),RPC数据(注册服务的名称),并且目标Handle的值为0(也就是Context Manager的handle),Driver层收到IPC数据,解析之后拿到Handle=0,就会去找到ContextManager,然后将IPC数据传递给ContextManager,ContextManager收到数据后,会根据IPC数据中的服务名称,将服务注册到自身的服务列表中,并分配handle编号。

当然这个过程是一个复杂的过程,涉及到很多driver层的数据结构,当Service Server向Context Manager注册自身服务的时候,binder driver会生成一个Binder节点,用来表示Service Server中的服务,接下来会生成Binder节点的引用数据,以便ContextManager识别所生成的Binder节点,并将相关节点连接起来,根据生成的顺序,引用数据会被编号,并插入到Ipc数据中,传递给ContextManager,ContextManager会根据IPC数据中的服务名称与Binder节点编号,将服务注册到自身的服务列表中。

image.png

检索

注册完成之后,这个服务就可以被其他进程调用了,但是调用的过程又需要借助ContextManager来实现,也就是服务检索的过程,假设服务A已经注册到ContextMananger中,现在客户端B要调用A,B首先将包含 RPC代码(GET_SERVICE)、RPC数据(请求的服务名)、Handle为0的IPC数据经过Binder Driver传递给ContextManager,contextManager解析后,拿到服务的名字,在自身持有的服务列表中进行搜索,查找相应的handle编号,然后将查到的handler编号发送给Binder Driver。Binder Driver根据传递过来的服务编号查找对应的引用数据,然后在客户端B生成引用数据。

image.png

调用

最后,客户端B将接受到的引用数据编号保存到Handler中,把与服务函数相关的RPC代码、RPC数据包含进IPC数据中,经由BinderDriver发送给指定的Service Server也就是服务A,并调用A中相关的函数。

image.png

Binder Driver函数分析

首先介绍一下Driver层几个比较重要的结构体:

  • binder_proc:用来描述一个正在使用binder进程通信机制的进程。当一个进程调用open函数时,binder驱动就会为它创建一个binder_proc结构体,它保存在一个全局的hash列表中,它用来管理Binder IPC所需要的各种信息,此外它拥有Binder中其他结构体的指针。

image.png

  • binder_buffer:用来描述一个内核缓冲区,它是用来在进程之间传递数据的,每一个使用Binder通信机制的进程,在Binder驱动程序中都有一个内核缓冲区列表,用来保存驱动程序为它分配的内核缓冲区

  • binder_node:用来描述一个Binder实体对象,每一个Service组件在Driver层中都对应一个binder_node实体对象,用来描述它在内核中的状态

下面是三个非常重要的函数
- 1.binder_open

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
/618165277)

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值