ServiceManger Binder的处理流程

news2024/11/13 15:57:35

陌生知识点如下:

  • BinderProxy:是将Native层的BpBinder对象进行封装后传给Java层使用的Binder对象
  • android_util_binder: Binder在JNI层的相关注册,处理,转换封装接口
  • BpBinder:Binder驱动在Native层的封装。
  • IPCThreadState:线程池对象
  • ServiceManager: 就像互联网的DNS服务器(地址为0)

以APP调用ServiceManager为例进行分析,分析ServiceManger Binder的处理流程:
SM内存放着许多<string, Binder>的数组,可以通过getService(String name)获取到对应用Binder,这是键值对。

final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 
-->ServiceManager.java->getService():
     -->IBinder service = sCache.get(name)
            return service
        rawGetService(name);
          -->final IBinder binder = getIServiceManager().getService(name);
                -->getIServiceManager()实现: //IServiceManager.aidl接口文件用于跨进程通信
                    -->sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()))
                          -->asInterface(Ibinder obj):
                             -->return new ServiceManagerProxy(obj); //返回一个Proxy的Binder对象。
                               --》ServiceManagerProxy是一个类: class ServiceManagerProxy Implements IServiceManager{
                                    在它的构造函数中:
                                    public ServiceManagerProxy(IBinder remote){
                                        mRemote = remote;
                                        mServiceManager = IServiceManager.Stub.asInterface(remote); //转成Proxy对象
                                    }
                               
                               }
                          //分析下面这个接口:这个是获取ServiceManager的IBinder,与其它Server的不同。
                          -->BinderInternal.getContextObject():
                             这个getContextObject接口的定义为:static final native IBinder getContextObject();//请进入Native看代码,返回的是BinderProxy对象(下面有说明)
                             -->android_util_Binder.cpp->gBinderInternalMethods[]={
                                 {"getContextObject", "...", android_os_BinderInternal_getContextObject}; //映射到右边的Native接口
                                ...
                             }
                             android_os_BinderInternal_getContextObject: //返回的是BinderProxy对象。(下面有说明)
                               -->sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
                                      -->ProcessState:就是一个进程,每个进程启动时就会启动一个ProcessState.
                                       //位于ProcessState.cpp中:Zygote Fork()一个进程时就会创建ProcessState,
                                       //或者也可以这么理解,ProcessState就是进程在Native层的一个表示
                                       //主要管理Binder驱动的初始化,管理Binder交互的线程池等操作
                                       //Native层的getContextObject主要目的是为了构建获取Native层的IBinder对象(BPBinder)。
                                       //所有进程获取的IBinder对象在Native层都由它获取,Binder创建也由ProcessState创建。

                                       
                                       sp<IBinder> context = getStrongProxyForHandle(0);
                                       //上面这个语句参数0:要特别注意,0就像固定的IP地址,指的就是ServiceManage服务。
                                       //SM是ServiceManager<name, binder>中的第0个对象,因为SM也是一个进程,它就像互联网中的DNS服务器,
                                       //DNS服务器的地址是公开的,所以这边SM的handle为0,是固定的,是列表中的第0号Binder对象。
                                         -->b = BpBinder::create(handle) //这个handle = 0; //创建SM的BpBinder并保存下来,方便后面再查找。
                                            result = b;
                                            return result;
                                       
                                  //BpBinder是给java使用的,所以要封装成java能识别的数据结构。
                                  //需要进行数据的转换与处理:这些是JNI的知识点    
                                  //下面接口返回的是基于BpBinder对像封装出来的BinderProxy对象(JAVA用)
                                  return javaObjectForIBInder(env,b); //b就是SM在Native的BPBinder.//返回的是jobject对象,是反射参数的java的BinderProxy
                                     //使用到Java中的反射:运行了BinderProxy.java中的getInstance()方法
                                     -->  jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
                                            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
                                        -->BinderProxy.java中的getInstance()方法:
                                           -->result = new BinderProxy(nativeData); //构建了BinderProxy对象,这个是Java层的Binder代理
                                           
             return binder;
        

通过前面的代码分析,可以得到一个结论,ServiceManager的Binder封装过程如下图所示:其它所有服务端提供的Service的Binder的封装逻辑也是相同的逻辑,举一反三。

下面再以更加简洁的流程描述上这整个获取ServiceManager过程的调用逻辑:

ServiceManagerProxy(它是一个Stub.Proxy对象)-》 IServiceManager.Stub.Proxy.getService():
  -->mRemote.transact();
    -->BinderProxy.cpp->transact(); //从ServiceManagerProxy->到BinderProxy,这一层是framework层
      -->transactNative();
        -->进入android_util_binder.cpp->android_os_BinderProxy_transact(); //这一层是JNI层
          -->数据类型转换,因为 下面要传给Native层
             parcelForJavaObject();
             IBinder* target=getBPNativeData();
             target->transact(); //target就是BpBinder ,这个接口调用进入BpBinder.cpp,进入Native层
               -->IPCTrheadState.cpp:IPCThreadState::self()->transact(); //安排一个线程去处理binder的通信传输
                 -->writeTransactionData(); //准备数据
                     -->将数据写入结构体中,这里省略。
                        mOut.write(cmd);
                        mOut.write(&tr, sizeof(tr)); //只是将数据放到mOut这个Parcel对象中,但还未发送

                 -->waitForResponse(); //这里是真正的发送数据的过程 。
                   -->talkWithDriver();
                       -->bwr.write_buffer = mOut.data() ; //取出out中的数据放到bwr中
                          ioctl(FD, BINDER_WRITE_READ, &bwr); //真正的发送数据,写到驱动中。
                       
                        

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.BGP状态机和路由注入方式

BGP状态机 BGP路由的生成 不同于IGP路由协议,BGP自身并不会发现并计算产生路由,BGP将GP路由表中的路由注入到BGP路由表中,并通过Update报文传递给BGP对等体。 BGP注入路由的方式有两种: Networkimport-route与IGP协议相同,BGP支持根据已有的路由条目进行聚合,生成聚合路由…

【Linux】多线程概念线程控制

文章目录 多线程概念Linux下进程和线程的关系pid本质上是轻量级进程id&#xff0c;换句话说&#xff0c;就是线程IDLinux内核是如何创建一个线程的线程的共享和独有线程的优缺点 线程控制POSIX线程库线程创建线程终止线程等待线程分离 多线程概念 Linux下进程和线程的关系 在…

Pygame编程(9)font模块

Pygame编程&#xff08;9&#xff09;font模块 函数示例 函数 pygame.font.init 初始化字体模块init() -> None pygame.font.quit 反初始化字体模块quit() -> None pygame.font.get_init True,如果字体模块已初始化get_init() -> bool pygame.font.get_default_font …

VUE笔记(九)vuex

一、vuex的简介 1、回顾组件之间的通讯 父组件向子组件通讯&#xff1a;通过props实现 子组件向父组件通讯&#xff1a;通过自定义事件($emit)方式来实现 兄弟组件之间的通讯&#xff1a;事件总线&#xff08;$eventBus&#xff09;、订阅与发布方式来实现 跨级组件的通讯…

django+MySQL计算机毕设之图片推荐系统(报告+源码)

图片推荐系统是在的数据存储主要通过MySQL。用户在使用应用时产生的数据通过Python语言传递给数据库。通过此方式促进图片推荐信息流动和数据传输效率&#xff0c;提供一个内容丰富、功能多样、易于操作的平台。述了数据库的设计&#xff0c;系统的详细设计部分主要论述了几个主…

win开机自启jar包

下载winsw工具 只需下载图中红框的工具 https://github.com/winsw/winsw/releases 文件配置 将下载的文件与jar文件放置在一起&#xff0c;两个文件名修改为服务名 编辑xml文件 注意不要出现中文&#xff0c; 标签内的jar文件地址要改为自己目录 <service><!-- I…

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个题目详解(逻辑类型题2)

题目内容 题目日本某地发生了一件谋杀案&#xff0c;警察通过排查确定杀人凶手必为4个嫌疑犯的一个。 以下为4个嫌疑犯的供词&#xff1a; A说&#xff1a;不是我。 B说&#xff1a;是C。 C说&#xff1a;是D。 D说&#xff1a;C在胡说 已知3个人说了真话&#xff0c;1个…

VUE笔记(十)Echarts

一、Echarts简介 1、什么是echarts ECharts是一款基个基于 JavaScript 的开源可视化图表库 官网地址&#xff1a;Apache ECharts 国内镜像&#xff1a;ISQQW.COM x ECharts 文档&#xff08;国内同步镜像&#xff09; - 配置项 示例&#xff1a;echarts图表集 2、第一个E…

腾讯音乐财务前景疲软,股价上涨势头难以持续

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 市场对腾讯音乐第二季度财报反应积极 猛兽财经之前在2023年6月12日发表的一篇文章中就曾分析过腾讯音乐&#xff08;TME&#xff09;股票&#xff0c;我们当时分析了腾讯音乐2023年第一季度的财务业绩。根据S P Capital IQ…

[halcon] 局部图片保存 gen_circle 和 gen_rectangle2 对比 这怕不是bug吧

背景 我想实现一个功能&#xff0c;获取图片中瑕疵的位置&#xff0c;将瑕疵周边的一块区域抠图并保存。 上代码 一开始我代码这么写的&#xff1a; gen_circle (Rectangle, Row[i], Column[i], 256) reduce_domain(Image,Rectangle,GrayEllipse) crop_domain(GrayEllipse,…

Mybatis中实现动态SQL

目录 1 背景2 if判断2 choose(when,otherwise)选择分支进入3 where4 set5 trim6 foreach循环遍历7 小结 1 背景 不建议使用&#xff0c;但是有些需求又不得不用回来温习下。动态SQL语句,也就意味着SQL语句不在是一成不变的而是具有多样性. 2 if判断 if的用法还是跟平常差不多…

[论文阅读笔记26]Tracking Everything Everywhere All at Once

论文地址: 论文 代码地址: 代码 这是一篇效果极好的像素级跟踪的文章, 发表在ICCV2023, 可以非常好的应对遮挡等情形, 其根本的方法在于将2D点投影到一个伪3D(quasi-3D)空间, 然后再映射回去, 就可以在其他帧中得到稳定跟踪. 这篇文章的方法不是很好理解, 代码也刚开源, 做一…

Git工作流

实际开发项目使用到的分支: main&#xff1a;生产环境&#xff0c;也就是你们在网上可以下载到的版本&#xff0c;是经过了很多轮测试得到的稳定版本。 release&#xff1a; 开发内部发版&#xff0c;也就是测试环境。 dev&#xff1a;所有的feature都要从dev上checkout。 fea…

【C51 GPIO的原理和内部结构】

51单片机项目基础篇 中篇&#xff1a;介绍GPIO1、认识GPIO2、GPIO 结构框图与工作原理2.1、P0端口结构框图与工作原理2.1.1、剖析组成 P0 口的每个单元的作用2.1.2、 P0 口做为 I/O 口及地址/数据总线使用时的具体工作过程 2.2、P1 端口结构框图与工作原理2.3、P2 端口结构框图…

求生之路2社区服务器sourcemod安装配置搭建教程centos

求生之路2社区服务器sourcemod安装配置搭建教程centos 大家好我是艾西&#xff0c;通过上文我们已经成功搭建了求生之路2的服务端。但是这个服务端是纯净的服务端&#xff0c;就是那种最纯粹的原版。如果想要实现插件、sm开头的命令等功能&#xff0c;需要安装这个sourcemod。…

JavaScript(笔记)

目录 Hello World JavaScript 的变量 JavaScript 动态类型 隐式类型转换 JavaScript 数组 JavaScript 函数 JavaScript 中变量的作用域 对象 DOM 选中页面元素 事件 获取 / 修改元素内容 获取 / 修改元素属性 获取 / 修改 表单元素属性 获取 / 修改样式属性 新…

如何可以管理监督员工工作微信?

自从微信管理系统研发上线之后&#xff0c;为了各企业带来了福音。 很多用户企业都是这样评论微信管理系统的&#xff1a;员工的所有微信聊天记录后台都可以清楚明了的看到&#xff0c;聊天记录都是永久保存的&#xff0c;不担心员工在手机上把聊天记录删除&#xff0c;杜绝员…

基于黑猩猩算法优化的BP神经网络(预测应用) - 附代码

基于黑猩猩算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于黑猩猩算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.黑猩猩优化BP神经网络2.1 BP神经网络参数设置2.2 黑猩猩算法应用 4.测试结果&#xff1a;5.Matlab代…

MyBatis 的关联关系配置 一对多,一对一,多对多 关系的映射处理

目录 一.关联关系配置的好处 二. 导入数据库表&#xff1a; 三. 一对多关系&#xff1a;-- 一个订单对应多个订单项 四.一对一关系&#xff1a;---一个订单项对应一个订单 五.多对多关系&#xff08;两个一对多&#xff09; 一.关联关系配置的好处 MyBatis是一…

Java——它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。

这是一个Java程序&#xff0c;它要求用户输入一个整数&#xff08;实际上是一个字符串&#xff09;&#xff0c;然后计算该整数的平方值&#xff0c;并将结果输出。程序的基本流程如下&#xff1a; 首先&#xff0c;声明并初始化变量data和result&#xff0c;它们的初始值都为…