Android之UI Automator框架源码分析(第九篇:UiDevice获取UiAutomation对象的过程分析)

news/发布时间2024/9/20 9:41:53

前言

    学习UiDevice对象,就需要看它的构造方法,构造方法中有UiDevice对象持有一些对象,每个对象都是我们分析程序的重点,毕竟UiDevice对象的功能,依赖这些组合的对象

    备注:当前对象持有的对象,初始化的位置一般在实例变量创建时或者构造方法中,以下是UiDevice构造方法中正在做初始化对象的代码!

UiDevice(Instrumentation instrumentation) {mInstrumentation = instrumentation;mQueryController = new QueryController(instrumentation);mInteractionController = new InteractionController(instrumentation);// Enable multi-window support for API level 21 and upif (UiDevice.API_LEVEL_ACTUAL >= Build.VERSION_CODES.LOLLIPOP) {// Subscribe to window informationAccessibilityServiceInfo info = getUiAutomation().getServiceInfo();info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;getUiAutomation().setServiceInfo(info);}
}

 UiAutomation对象很重要

        我们看到getUiAutomation()方法在UiDevice构造方法中的调用 

AccessibilityServiceInfo info = getUiAutomation().getServiceInfo(); info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS; getUiAutomation().setServiceInfo(info);

getUiAutomatrion()方法分析

位于UiDevice类中的getUiAutomation()方法,返回值是UiAutomation对象

    UiAutomation getUiAutomation() {return getUiAutomation(getInstrumentation());}

1、先调用一个getInstrumentation()方法

该方法返回的Instrumentation对象会再被传入到接受一个参数的getUiAutomation重载方法中

2、再次调用重载的getUiAutomation()方法

3、此重载方法的返回值将作为当前getUiAutomation()方法的返回值

我们先学习一下Instrumentation对象是如何获取到的,即getInstrumentation()的调用!

getInstrumentation()方法分析

    位于UiDevice中的getInstrumentation方法,返回值为Instrumentation对象

    Instrumentation getInstrumentation() {return mInstrumentation;}

    通过该方法就可以得到UiDevice对象持有的Instrumentation对象mInstrumentation,方法内部通过return语句返回mInstrumentation,说明Instrumentation对象已经初始化结束,这里只是返回

Instrumentation对象在哪初始化的

    通过代码得知,是创建UiDevice的时候,传入的一个Instrumentation对象

创建UiDevice对象

public static final UiDevice mDevice = UiDevice.getInstance(getInstrumentation());

这时候传入的其实是InstrumentationRegistry下的静态方法getInstrumentation()返回的Instrumenation对象。

public static Instrumentation getInstrumentation() {Instrumentation instance = instrumentationRef.get();if (null == instance) {throw new IllegalStateException("No instrumentation registered! " + "Must run under a registering instrumentation.");}return instance;
}

一个原子对象负责持有Instrumentation对象

找到了原子对象赋值的地方

我们需要找到registerInstance这个静态方法在哪里被调用即可

在MonitoringInstrumentation对象中的oncreate()方法中调用了

MonitoringInstrumentation对象,从名字上,果然是Instrumentation的子类,它是具体的对象,代码追踪到这里,只要再找到这个oncreate()方法在哪里调用即可!

很快找到了,追踪了整个Unit框架了都要

AndroidJUnitRunner是MonitoringInstrumentation的子类,看来AndroidJUnitRunner也是个Instrumentation!!

AndroidUnitRunner作为入口类

我们是在am instrument 指定的该类,这一切明白了,这个用到的Instrumentation对象,其实就是AndroidUnitRunner对象

$ADB shell am instrument -w -e class com.xxx.camauto.Common#unlockScreen com.xiaomi.camauto.test/androidx.test.runner.AndroidJUnitRunner

重载的静态方法getUiAutomation(Instrumentation)方法分析

位于UiDevice类中的静态方法getUiAutomation(),它接受一个Instrumentation对象,最后会返回一个UiAutomation对象

    static UiAutomation getUiAutomation(final Instrumentation instrumentation) {int flags = Configurator.getInstance().getUiAutomationFlags();if (UiDevice.API_LEVEL_ACTUAL > Build.VERSION_CODES.M) {return instrumentation.getUiAutomation(flags);} else {// Custom flags not supported prior to N.if (flags != Configurator.DEFAULT_UIAUTOMATION_FLAGS) {Log.w(LOG_TAG, "UiAutomation flags not supported prior to N - ignoring.");}return instrumentation.getUiAutomation();}}

1、获取配置对象中的UiAutomation的标志位

首先通过Configurator对象的getUiAutomationFlags方法,得到一个int值,该值的初始值是0,然后再将该int值赋值给局部变量flags存储,flags存储的是关于UiAutomatrion对象的标志位(说明:Configurator对象存储着UI Automator测试框架用到的各种配置信息,此时局部变量flags存储的值正是从Configurator对象中获得,后面单独文章总结)

2、系统版本大于API 23获取UiAutomation对象的方式

接着做API版本判断,UiDevice类持有的API_LEVEL_ACTUAL代表API版本,根据API版本执行不同的逻辑

当API版本大于M(API==23)时,使用的传入的Instrumentation对象的接受一个整型参数的getUiAutomation()方法,此时会将局部变量flags传入进去,getUiAutomation(int)方法返回的是一个UiAutomation对象(看这个flags决定了获取对象的不同)

3、系统版本小于等于API 23获取UiAutomation对象的方式

当API版本小于等于M(API==23)时,使用的是传入的Instrumentation对象的无参数的getUiAutomation()方法,该方法也会返回一个UiAutomation对象

说明:最终getUiAutomation()方法中依赖Instrumentaion对象获取到的UiAutomation对象

找到具体的UiAutomation对象

    从前面的步骤得知这个Instumentation对象其实是AndroidJUnitRunner,而调用的getUiAutomation()获取到的UiAutomation()对象,由于java是单继承,我们只要沿着AndroidJunitRunner的继承树, 找到getUiAutomation()方法,就能知道具体的UiAutomation对象在哪里创建的!!

1、先从AndroidJunitRunner中找getUiAutomation()方法,发现该类没有该方法

2、只能继续从它的父类MonitoringInstrumentation中找getUiAutomation()方法,这是面向对象程序的特点,记住了各位,结果还是没有这个方法

3、继续从它的父类ExposedInstumentationApi中查找,发现还是没有

4、继续从父类Instrumentation中查找,总算找到了

原来是UiAutomation对象,必须创建的时候才会创建,必须创建是指:没创建与已经销毁

可以看到把当前App上下文的主线程Looper对象传递进去了

总结

1、追踪了一圈,也知道UiAutomation对象是在哪里创建!

2、面向对象程序,子类找不到的方法,按照继承结构,继续向上找就对了。。 

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

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

生成式AI设计模式:综合指南

原文地址:Generative AI Design Patterns: A Comprehensive Guide 使用大型语言模型 (LLM) 的参考架构模式和心理模型 2024 年 2 月 14 日 对人工智能模式的需求 我们在构建新事物时,都会依赖一些经过验证的方法、途径和模式。对于软件工程师来说&am…

latex报错:Undefined control sequence.解决办法

经过分析是缺宏包了,\usepackage{amsmath}。 总结 在 VS Code 中编写 LaTeX 文档时,如果你遇到了 “Undefined control sequence” 错误,这通常意味着你尝试使用的某个 LaTeX 命令或宏没有被定义。在 LaTeX 中,很多公式和符号需要…

vue导出excel文件时出现了两个同样表格的重复数据

vue导出excel文件时出现了两个同样表格的重复数据 先看我的效果,这里重复了两次数据 解决办法: 是因为表格中列中有fixed的属性, 把这个属性去掉,然后从新导出就ok了!

MySQL基础(二)

文章目录 MySQL基础(二)1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 2. 多表设计2.1 一对多2.1.1 表设计2.1.2 外键约束 2.2 一对一2.3 多对多2.4 案…

k8s1.23.15集群二进制部署

一、前言 二进制部署1.23.15版本k8s集群,etcd集群部署与k8s集群节点复用,手动颁发集群证书 主机信息如下 主机名称ip地址服务k8s-master0110.1.60.125docker、etcd、kube-apiserver、kube-schduler、kube-controller-manage、kubelet、kube-proxyk8s-no…

省市区街道/乡镇四级联动vue3

最近优化了一个省.市.区/县、乡镇/街道的四级联动组件,技术栈是element vue3记录一下。 本来是这样的三级联动: 这个三级联动很简单,直接利用el-select组件把地区值带进去就行了,现在要优化成省.市.区/县、乡镇/街道的四级联动&…

C# 多线程(3)——线程池

文章目录 1 定义2 线程池使用3 安全取消线程池中任务 1 定义 线程是计算机宝贵的资源,频繁的创建和销毁线程将会大量的占用计算机资源(为每个线程单独分配内存空间,并且多线程下的CPU时间片的切换也会耗费一定的时间)。为了充分利…

LabVIEW眼结膜微血管采集管理系统

LabVIEW眼结膜微血管采集管理系统 开发一套基于LabVIEW的全自动眼结膜微血管采集管理系统,以提高眼结膜微血管临床研究的效率。系统集成了自动化图像采集、图像质量优化和规范化数据管理等功能,有效缩短了图像采集时间,提高了图像质量&#…

Langchain-Chatchat:离线运行的大模型知识库 | 开源日报 No.182

chatchat-space/Langchain-Chatchat Stars: 22k License: Apache-2.0 基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现的开源、可离线部署的检索增强生成 (RAG) 大模型知识库项目。该项目是一个可以实现完全本地化推理的知识库增强方案,重点解决数据安全保护…

Palworld 幻兽帕鲁面板开服教程

介绍 在本文档中,您将学习如何构建 Palworld 服务器。 关于 Palworld 通过设置服务器,您可以与您的 Palworld 好友以及其他玩 Palworld 的人共享同一个世界。 推荐的服务器设置 内存 由于至少一次内存泄漏,服务器需要大约 16-32GB RAM。…

FPGA之16:1复选器

每个slice 都有一个F8MUX。F8MUX原语: MUXF8 MUXF8_inst( .0(0),Il Output of MUX to general routing .I0(10),//Input(tie to MUXF7L/LO out) .I1&#xf…

纽约纳斯达克大屏投放受众群体有哪些-大舍传媒

纽约纳斯达克大屏投放受众群体有哪些-大舍传媒 1. 纳斯达克大屏的概述 纳斯达克大屏是全球金融市场中最出名的电子交易平台之一。作为一个重要的金融信息传递渠道,纳斯达克大屏吸引了来自全球的投资者的目光。在这个巨大的投放平台上,大舍传媒希望为客…

1.QT简介(介绍、安装,项目创建等)

1. QT介绍 Qt(官方发音 [kju:t])是一个跨平台的C开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序 Qt 是纯 C 开发的,正常情况下需要先学习C语言、然后在学习C然后才能使用…

计算机设计大赛 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖,适合作为竞赛课题方向&#xff0c…

【前端素材】推荐优质后台管理系统cassie平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的管理界面,通常由管理员和工作人员使用。它提供了访问和控制网站或应用程序后台功能的工具和界面,使其能够管理用户、内容、数据和其他各种功能。 2、功能需求 后台管理系…

【JavaEE】_前端使用GET请求的queryString向后端传参

目录 1. GET请求的query string 2. 关于query string的urlencode 1. GET请求的query string 1. 在HttpServletRequest请求中,getParameter方法用于在服务器这边获取到请求中的参数,主要在query string中; query string中的键值对都是程序…

Docker容器(3)单容器管理

一、单容器 1.1概念简介 Docker三个重要概念: 仓库(Repository); 镜像(Image); 容器(Container). *Docker的三个重要概念是仓库(Repository)、镜像(Image)和容器(Container)**。具体如下: **镜像(Image)**:Docker镜像是创建容器的基础,它类似…

SpringCloud(17)之SpringCloud Stream

一、Spring Cloud Stream介绍 Spring Cloud Stream是一个框架,用于构建与共享消息系统连接的高度可扩展的事件驱动微服务。该框架提供了一个灵活的编程模型,该模型建立在已经建立和熟悉的Spring习惯用法和最佳实践之上,包括对持久发布/子语义…

《读写算》杂志社读写算杂志社2024年第2期目录

教育资讯 教育部印发通知部署:做好2024年寒假期间校外培训治理工作 1《读写算》投稿:cn7kantougao163.com 北京提升学校心理健康工作水平——每校至少配备一名专职心理健康教育教师 1 湖北孝感:2026年达成小学毕业时人人会游泳 2…

C语言编程安全规范

目的 本规范旨在加强编程人员在编程过程中的安全意识,建立编程人员的攻击者思维,养成安全编码的习惯,编写出安全可靠的代码。 2 宏 2.1 用宏定义表达式时,要使用完备的括号 2.2 使用宏时,不允许参数发生变化 3 变量 …
推荐文章