Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

这篇具有很好参考价值的文章主要介绍了Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

前面几篇文章,为我们学习Binder IPC通信机制提供了扎实的理论基础,接下来将正式进入Binder IPC通信架构及原理的解读。
Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

一、Binder IPC 基础架构

Binder 是基于 C/S 架构的,由一系列的组件组成,包括 Client进程、Server进程、Service Manager进程、Binder 驱动。其中 Client进程、Server进程、Service Manager进程运行在用户空间,互相隔离,而Binder 驱动运行在内核空间。因此Client进程、Server进程、Service Manager 进程间的交互必须通过Binder驱动(系统调用 open、mmap 和 ioctl 函数来访问设备文件 /dev/binder,实现与 Binder 驱动的交互来间接的实现跨进程通信),而非直接交互的原因是,**因为Client进程、Server进程、Service Manager进程属于进程空间的用户空间,不可进行进程间交互,而Binder驱动属于进程空间的内核空间,可进行进程间(进程内)直接交互。**Binder IPC中的每一个Client、Server进程都各自独立维护着一个Binder线程池来处理IPC请求,因此Server、Client 进程都可以并发地发出IPC请求和响应IPC请求。

Server Manager进程与Binder驱动的交互也是通过Binder实现的。

Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

1、Binder IPC核心角色

由上图可知Binder IPC 主要参与角色有五种:

角色 说明 参与对象
Client进程 Binder服务的使用者 Binder 代理对象
Server进程 Binder服务的供应商 Binder本地对象
Service Manager进程 Binder服务的管理者,负责把Binder的名称到引用对象的转换,类似DNS的功能 \
Binder驱动 实现各种Binder的底层交互和管理,类似路由器。 Binder实体对象、Binder引用对象(实体的引用)

Server 进程启动时主动向Binder驱动发起注册自己的Service组件IPC请求,然后Binder驱动响应IPC请求并转发该请求给Service Manager进程,再由Service Manager进程注册管理该Service 组件,于是Service Manager进程拥有了对应Server进程的信息(即完成了服务注册)。当Client 进程向Service Manager进程发起携带服务唯一标识的获取服务IPC请求时,再次由Binder驱动响应并转发给Service Manager进程Service Manager进程根据注册信息找到对应的服务对象,交由Binder驱动返回给Client

2、Binder IPC的数据流

Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

二、Binder IPC 协议通信流程

Client进程和Server进程的一次IPC 流程可以从整体通信上分为五个步骤:

步骤 说明
1 Client 将通信数据封装为Parcel对象并传递到Binder驱动
2 Client向Binder驱动发送BC_TRANSACTION_COMPLETE协议,Binder驱动根据协议内容找到目标Server进程后回复一个BR_TRANSACTION_COMPLETE告知Client其通信请求已被接受,Client接到BR_TRANSACTION_COMPLETE并处理后,会再次进入到Binder驱动程序中等待Server进程的响应结果
3 Binder驱动在给Client回复一个BR_TRANSACTION_COMPLETE的同时,向目标Server进程发送一个BR_TRANSACTION返回协议,请求目标Server进程处理这个IPC请求
4 Server进程接受BR_TRANSACTION并处理后,给驱动回复一个BC_REPLY协议,驱动根据协议内容找到目标Client进程后再次向Server进程发送一个BR_TRANSACTION_COMPLETE返回协议,告知Server已接到返回的相应结果,Server接到并处理了BR_TRANSACTION_COMPLETE协议后,一次IPC流程就结束了,接着会重新进入到驱动程序中等待下一次IPC请求
5 Binder驱动在给Server进程发送BR_TRANSACTION_COMPLETE的同时,也会向目标Client进程发送一个BR_REPLY返回协议,代表Server进程已经处理完成IPC请求了并将结果返回给Client

从具体对象来看,一次Binder IPC (即Binder库 与 Binder 驱动的交互)需要至少五种核心对象参与:BpBinderBBinderBinder实体对象Binder代理对象Binder驱动程序。核心流程为BpBinder——>Binder引用对象——>Binder实体对象——>BBinder——>Binder 事务
Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

步骤 说明
1 Client进程里的Binder代理对象在向Binder驱动中的Binder引用对象发起IPC请求,Binder驱动根据Client进程传入过来的Binder 代理对象的句柄值(BpBinder中的mHandle)找到目标Binder引用对象
2 Binder驱动再根据Binder引用对象寻找对应的Binder实体对象并创建一个Binder事务,封装此次IPC请求。
3 Binder驱动在根据Binder实体对象找到运行在Server进程的Binder本地对象,将Client进程发送的IPC请求携带的数据交给Binder本地对象处理。
4 Binder本地对象在Server进程继续处理IPC请求,处理完成后将结果返回到Binder驱动Binder驱动把结果封装到步骤2创建的Binder事务中。
5 Binder 驱动最后根据Binder事务的相关属性,找到发出IPC请求的Client进程,并通知Client进程把结果返回给Binder代理对象处理。

在浏览器输入一个域名地址http://www.xxx.com 按下回车后,因为不能直接通过域名找到目标服务器,接着访问 DNS 域名服务器(保存了域名和IP的映射)筛选出目标服务器,然后通过这个 ip 地址才能放到到 http://www.xxx.com 对应的服务器。

三、Binder IPC 核心角色详解

1、Server 进程及Server 组件

Server 进程运行于进程空间内的用户空间,作为Binder服务的供应商,Server组件启动时通过Binder驱动主动把自己注册到Server Manager进程之中(即主动建立binder服务名称和Binder引用对象的映射),方便Client随时通过Server Manager进程获取相应的Binder代理对象进而得到使用其服务提供的能力。

同一个Server进程可以同时运行多个Server组件(即提供Binder服务的代码模块),同一个Client进程也可以同时向多个Server 组件发起IPC 请求,每一个请求对应一个Client组件(或者成为Server代理),
Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

2、Client进程及Client组件

Client进程是Binder服务的使用者,使用时通过Service Manager 进程通信获取Binder(本地对象的)代理对象,通过Binder代理对象经过Binder驱动去向Server进程发起IPC请求。

3、Service Manager 与实名 Binder

运行于用户空间的Service Manager守护进程是提供Binder服务的查询功能,根据注册时的Binder服务名称就能返回其对应的Binder引用对象,对于Binder服务通常是有一个唯一的字符串名称,主要想Servive Manager 注册了,应用就可以通过这个字符串名称来得到对应的Binder 引用对象,而Service Manager进程也是通过Binder IPC与其他进程进行通信的,至于实现细节后续再表,其作用就类似于DNS功能。

4、Binder 驱动

**Binder 驱动运行于内核空间,是整个Binder IPC的核心(由Android系统内核实现),Binder驱动实现open、mmap和ioctl系统调用,完成内核空间和用户空间缓存的映射以及对缓存和Server组件的管理。**包括不限于负责进程之间 Binder 通信的建立,Binder 在进程之间的传递,Binder对象生命周期管理(采用引用计数计数),数据包在进程之间的传递和交互等一系列底层支持,类似网络通信中路由器的功能。Server进程与Client进程的通信都需要依赖Binder驱动间接完成,Binder驱动抽象了一个虚拟设备文件dev/binder/并向用户空间暴露,使得应用程序进程可以通过它间接建立通信通道。

四、Binder 通信过程

Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)

BC_XXX代表用户空间的进程发送给Binder驱动的命令,而BR_XXX是Binder驱动返回给用户空间进程的命令。

至此,我们大致能总结出 Binder 通信过程:

  1. 首先,一个进程使用 BINDERSETCONTEXT_MGR 命令通过 Binder 驱动将自己注册成为 ServiceManager;
  2. Server 通过驱动向 ServiceManager 中注册 Binder(Server 中的 Binder 实体),表明可以对外提供服务。驱动为这个 Binder 创建位于内核中的实体节点以及 ServiceManager 对实体的引用,将名字以及新建的引用打包传给 ServiceManager,ServiceManger 将其填入查找表。
  3. Client 通过名字,在 Binder 驱动的帮助下从 ServiceManager 中获取到对 Binder 实体的引用,通过这个引用就能实现和 Server 进程的通信。

我们看到整个通信过程都需要 Binder 驱动的接入。下图能更加直观的展现整个通信过程(为了进一步抽象通信过程以及呈现上的方便,下图我们忽略了 Binder 实体及其引用的概念):

Binder驱动,通过虚拟出的物理设备(/dev/binder),连接Service进程、Client进程与Service Manager进程

七、开发使用Binder

Binder驱动、Service Manager进程属于Android基础架构是系统已经实现的,Client进程、Server 进程属于Android应用层需要开发者自己实现。跨进程通信时,开发者只需自定义Client、Server进程并显式使用上述3个步骤(注册服务,获取服务,使用服务),最终借助Android的基本架构功能就可完成进程间通信。

  • Binder机制在 Android中的实现主要依靠 Binder类,其实现了IBinder接口

  • 用一个应用Binder的实例来介绍怎么显式使用注册服务,获取服务,使用服务完成进程间通讯

以 Client进程通过Server进程实现加法函数(两个整数相加) 为例

  • Client进程将两个整数传给Server进程
  • Server进程将相加之后的结果返回给Client进程

1、注册服务

Server进程通过Binder驱动向ServiceManager进程注册服务

    sp<ProcessState> proc(ProcessState::self());
    sp<CalcService> service = new CalcService();
    sp<IServiceManager> sm = defaultServiceManager(); 
    sm->addService(“CalcService”, service);
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
  • ProcessState::self()调用ProcessState的构造函数,创建一个实例,该操作打开binder驱动,并进行mmap函数,映射出binder驱动对应的映射内存缓冲区
  • 创建CalcService实例,加法函数是CalcService的一个方法
  • 获取一个ServiceManager对象BpServiceManager
  • 调用BpServiceManager的addService方法,将服务(CalcService)注册到Service Manager
  • 创建线程池并加入线程池,执行主线程和工作线程
  • 注册服务后,Binder驱动持有 Server进程创建的Binder实体

2、获取服务

Client进程使用某个service前(此处是CalcService),需通过Binder驱动向ServiceManager进程获取相应的Service信息

sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(“CalcService”);
sp<ICalcService> calcService = interface_cast <ICalcService>(binder);
  • 获取一个ServiceManager对象BpServiceManager
  • 调用BpServiceManager的getService方法,根据服务名(“CalcService”)获取到ServiceManager管理的IBinder
  • 通过interface_cast调用asInterface()函数,返回IBinder的客户端,通过该客户端与服务端通讯。此时Client进程与Server进程创建了连接

3、使用服务

Client进程根据获取到的Service信息(Binder代理对象),通过Binder驱动建立与该Service所在Server进程通信的链路,并开始使用服务

3.1、Client进程将参数(整数a和b)发送到Server进程

status_t myAdd(int a, int b, String8& result)
{
	Parcel data, reply;
	data.writeInterfaceToken("CalcService");
	data.writeInt(a);
	data.writeInt(b);
	remote()->transact(CALC_ADD, data, &reply);
	//status_t ret = reply.readInt32();
	//String8 tempResult = reply.readString8();
	//result.setTo(tempResult);
	//return ret;	
}

目标参数与接口标识赋值,调用代理对象BpInterface的transact() 将上述数据发送到Binder驱动

transact(CALC_ADD, data, reply, 0)
// 参数说明:
// 1. CALC_ADD:目标方法的标识符(Client进程和Server进程自身约定,可为任意)
// 2. data :上述的Parcel对象
// 3. reply:返回结果
// 0:可不管
// 注:在发送数据后,Client进程的该线程会暂时被挂起,若Server进程执行的耗时操作,请不要使用主线程,以防止ANR

Binder驱动根据代理对象找到对应的真身Binder对象所在的Server 进程(系统自动执行),Binder驱动把数据发送到Server进程中,并通知Server 进程执行解包(系统自动执行)

3.2、Server进程根据Client进程要求调用目标方法(即加法函数)

收到Binder驱动通知后,Server 进程通过回调Binder对象onTransact()进行数据解包 & 调用目标方法

   status_t BnCalcService::onTransact(int code, Parcel data, Parcel reply, int flags){
         // code即在transact()中约定的目标方法的标识符
         switch (code) { 
               case CALC_ADD: { 
   				String8 tempResult;
   				//获得目标方法的参数
   				int arg0 = data.readInt();
   				int arg1 = data.readInt();
   				//调用服务端方法进行计算
   				status_t ret = myAdd(arg0, arg1, tempResult);
   				//将计算结果写入到reply返回
   				reply->writeInt32(ret);
   				reply->writeString8(tempResult);
   				return NO_ERROR;			
   			}
   		}
   	}

将结算结果返回到Binder驱动文章来源地址https://www.toymoban.com/news/detail-406130.html

3.3、Server进程将目标方法的结果(即加法后的结果)返回给Client进程

  • Binder驱动根据 代理对象 沿原路 将结果返回 并通知Client进程获取返回结果
  • 通过代理对象 接收结果(之前被挂起的线程被唤醒)
   status_t ret = reply.readInt32();
   String8 tempResult = reply.readString8();
   result.setTo(tempResult);

到了这里,关于Android 进阶——Binder IPC之Binder IPC架构及原理概述(九)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Binder通信原理(二):servicemanager启动

    源码基于: Android R 下图是android 8.0 之前binder 的软件框架,依赖的驱动设备是/dev/binder,binder机制的四要素分别是client、server、servicemanager和binder驱动。 对于android 8.0后的binder 和vndbinder依然同这个框架,只不过驱动的设备多加/dev/vndbinder 这篇主要分析servicemanger的流程,hwserv

    2024年02月11日
    浏览(31)
  • 写给 Android 应用工程师的 Binder 原理剖析

    这篇文章我酝酿了很久,参考了很多学习文档,读了很多源码,却依旧不敢下笔。生怕自己理解上还有偏差,对大家造成误解,贻笑大方。又怕自己理解不够透彻,无法用清晰直白的文字准确的表达出 Binder 的设计精髓。直到今天提笔写作时还依旧战战兢兢。 Binder 之复杂远远

    2024年02月13日
    浏览(45)
  • Android Binder通信原理(七):java 下的C-S

    源码基于: Android R 在之前的几篇博文中,对Android binder 的通信原理进行的深入的剖析,这些博文包括: binder 简介 、 servicemanager启动 、 service注册 、 service获取 、 Java 端的service 注册和获 取。 在前一文中,通过实例,详细地说明了 native 下 的C-S 通信原理 。 本文在之前的基

    2024年02月11日
    浏览(29)
  • Android Binder通信原理(五):Java 端的service 注册和获取

    源码基于: Android R 在阐述相关的知识点,先整理个框架图,后面带着框架图来分析过程: Java 端对于binder 使用大致分为: Java client Java service Java client native service Java 端service 的注册使用 ServiceManager.addService() Java 端service 的获取使用 ServiceManager.getService() 入口都是通过 Servic

    2024年02月11日
    浏览(28)
  • MySQL概述,架构原理

            MySQL是一个关系型数据库管理系统,由瑞典的MySQL  AB公司开发,后被oracle公司收购,MySQL是当下最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(Relational Database Management System,关系数据库管理系统)应用软件之一。         MySQL所使用的

    2024年02月11日
    浏览(30)
  • 需求分析引言:架构漫谈(五)架构师成长之路

    我研发领域也从事了一些年,期间也做过一些架构设计工作,包括C#单体转型为Java微服务、Python单体转型为Java微服务等, 也尝试着从自己的经验角度,来汇总一些知识点,同时描述一下如何成长为一个合格的软件架构师,仅供参考,也欢迎跟我一起探讨。 顾名思义,架构师

    2024年02月13日
    浏览(31)
  • 需求分析引言:架构漫谈(一)

    本文主要对架构的概念做一些介绍,并引申出需求分析的重要性。 后续准备做一个系列,定期介绍我工作以来的一些需求实现的案例。 注:因为架构的内容比较庞大,里面的每个点,都可以扩展成一系列的文章, 因此,本文只是漫谈,多数内容仅做介绍,后续有时间,我再

    2024年02月10日
    浏览(31)
  • 网络安全引言(网络安全概述、计算机安全、OSI安全体系、网络安全模型)

    1.1 网络中的“安全”问题 信息安全经历两大变革: 从物理和管理方法 转变成 自动化工具保护信息安全 终端普遍使用 网络传输数据并保证数据安全 网络中的“安全”问题 监听 截获 篡改 假冒 假冒网点 Email截取 否认 1.2 网络安全定义 网络安全是一个跨多门学科的综合性科

    2024年02月19日
    浏览(37)
  • 安卓进阶之android系统架构

    安卓进阶躲不开阅读源码和深入了解安卓的底层,这是一篇入门级别的文章,可以对安卓架构有个大体的认识。 首先要理解andriod和AOSP的关系,我们日常开发的安卓跟市面上的安卓不是一个意思,我们开发的是安卓app,市面上的安卓其实是安卓系统。 维基百科: Android 是基于

    2023年04月12日
    浏览(23)
  • 云计算:从基础架构原理到最佳实践之:云计算概述与发展历程

    作者:禅与计算机程序设计艺术 随着信息技术的不断发展,在国际化进程中,越来越多的人们开始把注意力转移到了云计算这个新兴领域,而这一热门技术也带动了一些新的变化。由于云计算的快速发展和普及,使得许多IT企业和开发者都开始关注其背后的技术细节。因此,

    2024年02月08日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包