Framework源码分析(二):Binder

2024-06-05 16:18
文章标签 分析 源码 framework binder

本文主要是介绍Framework源码分析(二):Binder,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Binder是什么

Binder是Android系统提供的一种进程间通信机制,它提供远程过程调用功能(RPC)。而这个机制形成,是通过一些系统组件构成的,分别是Client、Server、ServiceManager和Binder Driver。Binder Driver是Binder驱动程序,运行在Linux内核空间;Client,Server和Service Manager运行在用户空间。

Binder进程间通信机制

Binder的C/S模型原理

既然关于Binder机制的组成知道了,那么就有必要了解一下这块的原理了。

1. Framework层

在Framework层,ServiceManager提供了对于系统中大大小小的Manager类的服务管理,比如ActivityManager,WindowManager等。这些Manager相应的服务通过与ServiceManager远程通信将他们注册在ServiceManager里。

Binder的C/S模型图

当Client发出向Server的请求时,ServerManager会通过Client发出的请求命令判断由哪个ManagerService进行处理,ServiceManager会将相应的Service取出,Client获取到Service的引用,通过这个引用即可向远程Server发送请求数据,Server处理完成之后会给Client一个返回响应。这样就完成了一个C/S的请求/响应的过程。

Client从ServiceManager获得Service的远程接口

2. Android应用层

在Android应用层,用户会自行编写自己的业务Service类,如果要实现远程通信的话需要继承Binder。如此操作,Client在调用了bindService()之后,Server会返回一个包含自己业务逻辑的IBinder对象给Client。Client通过这个对象即可获取Server中的数据,达成与Server之间的通信。

其实,不管是Framework层还是Android应用层,实现通信的原理正是依靠Binder建立Client和Server之间的联系,然后通过Binder驱动完成Client和Server之间的数据交互。

Binder的工作机制

接下来聊聊Binder的工作机制。

Binder工作机制

通过上图,我们可以看出binder的工作流程是这样实现的:
(1)Client发送请求给Server,在Server未返回结果前,Client处于阻塞状态。请求的数据和相应操作交给Client的Proxy处理。
(2)Proxy代理将数据封装后,交给Binder驱动程序进行数据的传输调度。(transact())
(3)Binder驱动程序将数据发送个Server,Server对数据进行解析,并根据相应的操作标识进行相应的操作处理。
(4)Server操作完成之后,将执行之后结果数据封装。然后将数据交给Binder驱动程序调度。(onTransact())
(5)Binder驱动程序将结果数据交给Client的Proxy代理,Proxy代理将数据解析后将最终结果返回给Client。
(6)Client接收到数据之后,结束阻塞状态。

Client和Server之间如何实现数据共享

在了解了关于Binder的模型和工作机制之后,接下来讨论一下关于数据共享的问题。由于进程之间是不能直接进行数据共享的,那么Client和Server之间的通信是怎么做到的呢?

关于C/S模型中的数据共享问题

1. 共享的数据

通过上图我们可以看出:
(1)数据的发送和接收是通过Binder驱动程序调度完成的。
(2)Binder驱动处理完发送方请求操作之后,会把数据写入到缓存区。该缓存区域对于接收方来说是“读缓冲区”(binder_write_read.write_buffer)
(3)接收方会读取缓存区中的数据,在未读取到数据之前,接收方一直处于阻塞状态。
(4)接收方在接收到数据之后,会把返回结果用binder_transaction_data结构体封装,写入缓冲区。

总结:数据的共享是发送方和接收方通过互相获取对方缓冲区里的数据完成的。这样做的优点是通过建立公共的缓存区,发送方和接收方均可操作这块内存空间的数据,不需要再申请其他内存。

2. Binder实体和引用问题

我们可以思考一个问题,在Binder的工作机制中,我们是依赖binder驱动程序去执行数据的调度,发送方依赖binder打包数据,接收方依赖binder回传数据。那么双方使用的binder真正意义上是什么?带着这个问题,我们可以看看下面的图。

Server向ServiceManager注册服务

注册流程是这样的:
(1)Server在自己的进程中向Binder驱动程序申请创建一个作为自己Service的Binder实体。
(2)Binder驱动程序为这个Service创建位于内核中binder实体节点和binder引用,然后将Service的名称和binder的引用传给ServiceManager,通知ServiceManager注册相应的Service服务。
(3)ServiceManager接收到数据之后,根据Service的名称和binder引用填写入一张表中。

Client从SericeManager获取Service的远程接口

如果这时Client向Server发送申请该Service服务请求时,ServiceManager就会通过该服务的名称,查找表获取相应服务的binder引用,返回给Client。

总结:作为数据发送方,它持有Binder的实体;作为数据接收方,它持有Binder的引用。

小结

在本次博客,重点针对Binder的工作机制以及Binder如何实现数据共享进行了详细描述。由于binder这部分知识体系过于庞大,因此还未涉及到C/C++的底层代码,因此这也是我本人在未来学习道路上要攻克的难题。对于不了解这部分知识的同学,建议通过阅读我的第一篇Framework文章《Framework源码分析(一):ActivityManagerService》来帮助你理解本篇文章。


这篇关于Framework源码分析(二):Binder的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1033551

相关文章

Linux中的more 和 less区别对比分析

《Linux中的more和less区别对比分析》在Linux/Unix系统中,more和less都是用于分页查看文本文件的命令,但less是more的增强版,功能更强大,:本文主要介绍Linu... 目录1. 基础功能对比2. 常用操作对比less 的操作3. 实际使用示例4. 为什么推荐 less?5.

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

Java集成Onlyoffice的示例代码及场景分析

《Java集成Onlyoffice的示例代码及场景分析》:本文主要介绍Java集成Onlyoffice的示例代码及场景分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 需求场景:实现文档的在线编辑,团队协作总结:两个接口 + 前端页面 + 配置项接口1:一个接口,将o

IDEA下"File is read-only"可能原因分析及"找不到或无法加载主类"的问题

《IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题》:本文主要介绍IDEA下Fileisread-only可能原因分析及找不到或无法加载主类的问题,具有很好的参... 目录1.File is read-only”可能原因2.“找不到或无法加载主类”问题的解决总结1.File

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Dubbo之SPI机制的实现原理和优势分析

《Dubbo之SPI机制的实现原理和优势分析》:本文主要介绍Dubbo之SPI机制的实现原理和优势,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Dubbo中SPI机制的实现原理和优势JDK 中的 SPI 机制解析Dubbo 中的 SPI 机制解析总结Dubbo中

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整