栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Binder机制---IPC、RPC的过程,69个经典Android面试题和答案详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Binder机制---IPC、RPC的过程,69个经典Android面试题和答案详解

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

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

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

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

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

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

此图为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节点编号,将服务注册到自身的服务列表中。

检索

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

调用

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

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/93a78a38732b4181bcf98beefc799b65~tplv-k3u1f

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

bpfcp-watermark.image)

Binder Driver函数分析

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

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

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

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

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

进程在使用Binder Driver时,首先要调用binder_open()函数,binder_open()与系统函数open()连接在一起,当进程调用open()函数时,Binder Driver的节点文件“dev/binder”将作为参数传给所调用的函数,Binder Driver的文件描述符作为返回值返回给进程。在调用mmap()和ioctl()时,该文件描述符将作为参数传给函数。

binder_open()函数将为打开Driver的进程生成binder_proc结构体

640237373747)] binder_open()函数将为打开Driver的进程生成binder_proc结构体

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678563.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号