当前位置: 首页 > news >正文

ServiceManager接收APP的跨进程Binder通信流程分析

现在一起来分析Server端接收(来自APP端)Binder数据的整个过程,还是以ServiceManager这个Server为例进行分析,这是一个至下而上的分析过程。

在分析之前先思考ServiceManager是什么?它其实是一个独立的进程,由init解析init.rc文件并由它创建,要早于zygote进程,ServiceManager的main函数进程文件位于:framework/native/cmds/servicemanager/main.cpp
这个main函数运行意味着系统的SM进程开始运行了。下面是ServiceManager在init.rc中的描述。

下面是ServiceManager.rc文件

 

上面的rc文件描述说明servicemanager是一个系统的关键服务进程,不能重启的,因为 它一旦重启,将会restart如healthd,zygote, audioserver, surfaceflinger, inputflinger等一系列重要的其它进程。

下面先给出一个非常重要的结论,就是ServiceManager的父类继承关系,最顶层的父类是IServiceManager和BBinder,后面的源码分析的时候这个很有用,否则看不懂代码。

 

 

大家知道,每个android系统关键进程或app进程启动时会先创建binder,我们从SM的进程代码进行分析,如下:

main.cpp->main()-->char* driver="/dev/binder";//启动初始化binder驱动:普通app进程是通过ProcessState::self()->new ProcessState()来启动进程然后在构造函数中初始化binder,//与SM启动创建binder一样sp<ProcessState> ps = ProcessState::initWithDriver(driver);-->return new ProcessState();//在构造函数中open_driver(driver);//实例化ServiceManagersp<ServiceManager> manager = new ServiceManager(std::make_unique(Access));//设置服务端的BBinder对象//所以manager就是一个BBinder对象:因为class ServiceManager: public os:BnServiceManager{}//而BnServiceManager继承关系是: class BnServiceManager: public ::android::BnInterface<IServiceManager>{ }//BnInterface的继承关系(位于Interface.h): class BnInterface: public BBinder{ }//综上,manager就是一个BBinder对象。//注意BnServerManager.h这个头文件是需要根据IServerManager.aidl文件自己去编译生成的(//可以使用AIDL命令去编译)IPCThreadState::self()->setTheContextObject(manager); -->IPCThreadState.cpp->self():-->return new IPCThreadState(); //创建线程对象IPCThreadState.cpp->setTheContextObject(sp<BBinder> obj):-->the_context_object = obj;//设置成为binder驱动的context Manager,成为上下文的管理者,ps代表SM进程ps->becomeContextManager(nullptr, nullptr);//重点在下面://通过Looper epoll机制处理binder事务sp<Looper> looper = Looper::prepare(false);//设置callbackBinderCallback::setupTo(looper);//向Binder驱动发送BC_ENTER_LOOPER事务请求,并获得binder设备的文件描述符//监听binder_fd文件描述符的数据变化-->IPCThreadState::self()->setupPolling(&binder_fd);looper->addFd(binder_fd, Looper::POLL_CALLBACK,Looper::EVENT_INPUT, cb, nullptr);-->//当binder驱动发来消息后:调用下面的回调事件处理:int handleEvent(int fd int event){//从binder驱动接收到消息并处理。IPCThreadState::self()->handlePolledCommands();-->do //当读 缓存中数据未消费完时,持续循环读{result = getAndExecuteCommand();-->result = talkWithDriver();//从Binder驱动读入数据mIn-->cmd = mIn.readInt32(); //从数据中读取BR响应码-->executeCommand(cmd);-->case BR_TRANSACTION: //走这个分支//对SM来说,使用the_context_object这个BBinder对象//而transact应该在SM的父类中定义即BBinder-->the_context_object->transact(tr.code,buffer,&reply,tr.flags);-->BBinder.cpp->transact()://这里注意,下面调用的其实是子类的onTransact(即BnServiceManager.h中定义,但这只是一个头文件)//更进一步分析,其实是调用由IServiceManager.aidl生成的Bn端的cpp文件中(需要自己编译)--> onTransact();-->IServiceManager.cpp->BnServiceManager::onTransact():-->getService(); //其实是它的孩子即ServiceManager的接口-->ServiceManager.cpp->getService(name, sp<IBinder> * outBinder);//返回Binder*outBinder = tryGetService(name, true);-->std::map<string16, sp<IBinder>> mNameToService; //维持一张表--> auto it = mNameToService.find(name);service = &(it->second); //取出Service;out = service->binder;return out;}while(mIn.dataPosition() < mIn.dataSize());  //当我们清空执行完所有的命令后,最后处理BR_DECREFS和BR_RELEASEProcessPendingDerefs();FlushCommands();  }

上面分析的应该比较详细了,下面再总结下整体流程:

总结:

  1. binder驱动收到请求后, SM的looperCallBack回调会进行处理(BinderCallback- >handleEvent)
  2. 然后调用IPCThread::self()->handlePolledCommands()解读命令,向上分发
  3. the_context_object(注意这是一个BBinder对象)即BBinder->transact();
  4. 转交给BBinder的子类BnServiceManager.onTransact()处理,但这个是AIDL提供的代码,所以真正实现的是ServiceManager.getService();

最后再画一张图描述下整个过程:

 

相关文章:

ServiceManager接收APP的跨进程Binder通信流程分析

现在一起来分析Server端接收&#xff08;来自APP端&#xff09;Binder数据的整个过程&#xff0c;还是以ServiceManager这个Server为例进行分析,这是一个至下而上的分析过程。 在分析之前先思考ServiceManager是什么&#xff1f;它其实是一个独立的进程&#xff0c;由init解析i…...

Git问题:解决“ssh:connect to host github.com port 22: Connection timed out”

操作系统 Windows11 使用Git IDEA 连接方式&#xff1a;SSH 今天上传代码出现如下报错&#xff1a;ssh:connect to host github.com port 22: Connection timed out 再多尝试几次&#xff0c;依然是这样。 解决 最终发现两个解决方案&#xff1a;&#xff08;二选一&#xf…...

在Eclipse中创建javaweb工程

新建动态web工程 点击project或other之后&#xff0c;如何快速找到Dynamic Web Project 填写工程名等详细信息 也许会出现下面的对话框 项目结构图...

Pycharm链接远程mysql报错

Pycharm链接远程mysql配置及相应报错如下&#xff1a; 解决方法&#xff1a; 去服务器确认Mysql版本号&#xff1a; 我的Mysql为5.7.43&#xff0c;此时Pycharm mysql驱动为8.0版本&#xff0c;不匹配&#xff0c;所以需要根据实际的版本选择对应的驱动&#xff1b;选择对应的版…...

【硕士论文完美复现】【价格型需求响应】基于需求侧响应的配电网供电能力综合评估(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Android Okhttp 源码浅析三

核心方法 getResponseWithInterceptorChain() internal fun getResponseWithInterceptorChain(): Response {// Build a full stack of interceptors.val interceptors mutableListOf<Interceptor>()interceptors client.interceptorsinterceptors RetryAndFollowUpI…...

一分钟学会用pygame制作棋盘背景

一分钟一个Pygame案例&#xff0c;这一集我们来学习一下如何生成一个视频中的棋盘背景效果&#xff0c;非常非常简单。 视频教程链接&#xff1a;https://www.bilibili.com/video/BV17G411d7Ah/ 当然我们这里是用来做页面的背景&#xff0c;你也可以拿来做别的效果&#xff0…...

Java --- 包装类

一、包装类 Java针对八种基本数据类型定义了相应的引用类型&#xff1a;包装类&#xff08;封装类&#xff09;。 二、基本数据类型与包装类的基本转换 public class WrapperTest {public static void main(String[] args) {//基本数据类型转换为包装类Boolean aBoolean new…...

[运维] wvp 28181安装部署全流程(ubuntu2204)

部署wvp 系统环境 系统版本&#xff1a;ubuntu2204 安装相关工具 sudo apt update ## 编译工具 sudo apt install git openjdk-11-jdk tar vim cmake gcc g libsrtp2-dev libssl-dev ## ffmepg sudo apt install ffmpeg编译zlm 编译zlm git clone https://gitee.com/xia-…...

vue实现富文本

效果图展示 一、安装依赖 npm install vue-quill-editor --save二、具体使用 html <template><!-- 富文本 --><quill-editorref"myQuillEditor"v-model"content":options"editorOption"blur"onEditorBlur($event)"…...

uniapp 开发微信小程序使用echart的dataZoom属性缩放功能不生效!bug记录!

在本项目中使用的是这个echart库 在项目中添加了dataZoom配置项但是不生效&#xff0c;突然想到微信小程序代码大小的限制&#xff0c;之前的echarts.js是定制的&#xff0c;有可能没有加dataZoom组件。故重新定制echarts.js。之前用的echarts版本是5.0.0&#xff0c;这次也是…...

用户端Web自动化测试_L4

目录&#xff1a; selenium多浏览器处理执行 javascript 脚本headless无头浏览器使用capability配置参数解析企业微信实战cypress测试框架介绍Playwright测试框架介绍 1.selenium多浏览器处理 多浏览器测试背景 用户使用的浏览器(firefox,chrome,IE 等)web 应用应该能在任何…...

CAPL - Panel和TestModule结合实现测试项可选

目录 一、定义脚本编号和脚本组编号 1、测试组定义 2、测试脚本编号定义...

机器学习,过拟合与欠拟合,正则化与交叉验证

目录 机器学习 过拟合与欠拟合 正则化与交叉验证 正则化 交叉验证 机器学习 的目的是使学到的模型不仅对已知数据而且对未知数据都能有很好的预测能力。 不同的机器学习方法会给出不同的模型。当损失函数给定时&#xff0c;基于损失函数的模型的训练误差&#xff08;tra…...

gradio使用transformer模块demo介绍1:Text Natural Language Processing

文章目录 文本生成 Text Generation自动完成 Autocomplete情感分析 Sentiment Analysis命名实体识别 Name Entity Recognition NER多语种翻译文本生成 Text Generation import gradio as gr from transformers import pipelinegenerator = pipeline(text-generation, model=&l…...

算法通关村——数论经典问题解析

1. 辗转相除法 主要目的是获取两个数里面的最大公约数。 public int gcd(int a, int b) {int k 0;do {k a % b;a b;b k;} while (k ! 0);return a;}2. 素数和合数 素数的要求是必须大于等于2&#xff0c;并且只能被1和它本身整除。 判断的方法比较简单&#xff0c;就是从…...

代码随想录算法训练营第四十六天|LeetCode 1143,1035,53

目录 LeetCode 1143.最长公共子序列 动态规划五步曲&#xff1a; 1.确定dp[i][j]的含义 2.找出递推公式 3.初始化dp数组 4.确定遍历顺序 5.打印dp数组 LeetCode 1035.不相交的线 LeetCode 53.最大子序列和&#xff08;动态规划&#xff09; 动态规划五步曲&#xff1a; 1.确定…...

leetcode 541.反转字符串II

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/reverse-string-ii/ ps&#xff1a; 这道题描述的有点晦涩难懂&#xff0c;意思就是每隔k个反转k个&#xff0c;末尾不够k个时全部反转&#xff0c;开始就不够k个也全部反转。 代码&#…...

MyBatis与Spring整合以及AOP和PageHelper分页插件整合

目录 前言 一、MyBatis与Spring整合的好处以及两者之间的关系 1.好处 2.关系 二、MyBatis和Spring集成 1.导入pom.xml 2.编写配置文件 3.利用mybatis逆向工程生成模型层代码 三、常用注解 四、AOP整合pageHelper分页插件 创建一个切面 测试 前言 MyBatis是一个开源的…...

《认知觉醒》读书笔记之潜意识

模糊--人生是一场消除模糊的比赛。 学习知识&#xff0c;消除认知模糊 掌握的工具越多&#xff0c;认知能力越强&#xff0c;消除模糊的能力就越强。 元认知-----》 如何反观自己。 刻意练习----》 如何精进自己。 运动改造大脑---》 如何激化自己的运动热情。 学习知识的…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...