上一篇文章《UIAutomator源代码分析之启动和执行》我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程。过程中我们也描写叙述了UiAutomatorBridge这个类的重要性,说它相当于UiAutomation的代理(我们都知道UiAutomator是通过UiAutomation和AccessibilityService进行连接然后获取界面空间信息和注入事件的).那么今天開始我们就环绕这个类以及跟它有关系的类进行进一步的分析。

1. UiAutomatorBridge框架

这一章节我们会先看UiAutomatorBridge的总体框架,往后我会编写其它文章通过一些详细的样例把它们串起来。由于我的mackbook pro上没有安装类图软件,所下面图是手画的

往下我们就去初步描写叙述下UiAutomatorBridge跟每个相关的类的关系。

2. UiAutomatorBridge与UiAutomation的聚合关系

UiAutomatorBridge拥有一个UiAutomation的成员变量,它们是聚合的关系,注意不是组合,由于UiAutomation不一定仅仅能依赖UiAutomatorBridge而存在,我们上一章节的UiAutomatorTestRunner就拥有一个UiAutomation的成员变量。

一旦UiAutomator工具须要通过UiAutomatorBridge获取界面或者注入事件的时候。就会调用该成员变量.比方以下这个非常关键的去获取当前界面的Root Node的方法:

/*     */   public AccessibilityNodeInfo getRootInActiveWindow() {
/* 66 */ return this.mUiAutomation.getRootInActiveWindow();
/* */ }

3. UiAutomatorBridge与QueryController的关联关系

QueryController做的全部事情就是去把UiSelector这个UI控件选择子翻译成真实的适合我们使用的android.view.accessibility.AccessibilityNodeInfo。

UiAutomatorBridge拥有一个成员变量mQueryController保存了QueryController的一个实例:

/*     */   private final QueryController mQueryController;
/* */

当UiObject须要获取一个UiSelector指定的控件信息时,会去调用UiAutomatorBridge的getQueryController方法来获得这个mQueryController对象来进行对应的操作。例如以下面的UiObject的方法findAccessibilityNodeInfo就是这样做的:

/*      */   protected AccessibilityNodeInfo findAccessibilityNodeInfo(long timeout)
/* */ {
/* 164 */ AccessibilityNodeInfo node = null;
/* 165 */ long startMills = SystemClock.uptimeMillis();
/* 166 */ long currentMills = 0L;
/* 167 */ while (currentMills <= timeout) {
/* 168 */ node = getQueryController().findAccessibilityNodeInfo(getSelector());
/* 169 */ if (node != null) {
/* */ break;
/* */ }
/* */
/* 173 */ UiDevice.getInstance().runWatchers();
/* */
/* 175 */ currentMills = SystemClock.uptimeMillis() - startMills;
/* 176 */ if (timeout > 0L) {
/* 177 */ SystemClock.sleep(1000L);
/* */ }
/* */ }
/* 180 */ return node;
/* */ }

该getQueryController方法会去调用UiAutomatorBridge的getQueryController方法:

/*      */   QueryController getQueryController()
/* */ {
/* 100 */ return UiDevice.getInstance().getAutomatorBridge().getQueryController();
/* */ }

从上面的类图我们能够看到,除了UiAutomatorBridge会调用QueryController做事情外,QueryController又会反过来调用UiAutomatorBridge来做事情,由于如图所描写叙述的,仅仅有UiAutomatorBridge拥有UiAutomation的实例,所以QueryController会持有一个UiAutomatorBridge的实例:

/*     */   private final UiAutomatorBridge mUiAutomatorBridge;

然后在须要的时候再调用UiAutomatorBridge,如以下的获得Root Node的方法:

/*     */   protected AccessibilityNodeInfo getRootNode()
/* */ {
/* 168 */ int maxRetry = 4;
/* 169 */ long waitInterval = 250L;
/* 170 */ AccessibilityNodeInfo rootNode = null;
/* 171 */ for (int x = 0; x < 4; x++) {
/* 172 */ rootNode = this.mUiAutomatorBridge.getRootInActiveWindow();
/* 173 */ if (rootNode != null) {
/* 174 */ return rootNode;
/* */ }
/* 176 */ if (x < 3) {
/* 177 */ Log.e(LOG_TAG, "Got null root node from accessibility - Retrying...");
/* 178 */ SystemClock.sleep(250L);
/* */ }
/* */ }
/* 181 */ return rootNode;
/* */ }

4. UiAutomatorBridge与InteractionController的关联关系

道理与以上的QueryController一样。仅仅是UiAutomatorBridge须要通过InteractionController做的事情不是去获得控件信息。而是去注入事件。

5. UiAutomatorBridge与ShellUiAutomatorBridge的继承关系

UiAutomatorBridge是一个抽象类,里面的方法有下面几个:

  • getRootInActiveWindow :通过UiAutomation获取当前窗体控件xml信息的根节点(通过它能够循环获取全部控件)
  • injectInputEvent :通过UiAutomation注入事件
  • waitForIdle :   通过UiAutomation睡眠指定时间

  • executeCommandAndWaitForAccessibilityEvent:通过UiAutomation运行指定线程的操作然后等待预期的时间返回

  • takeScreenshot :通过UiAutomation进行截图

  • performGlobalAction :  通过UiAutomation去运行一些全局的动作。如打开近期打开过的app列表,回到home界面等

从中能够看到这些动过都是须要通过UiAutomation来运行的,但也有一些动作是不须要用UiAutomation运行的,所以我相信google是为了代码清晰和可维护性,提供了子类ShellUiAutomatorBridge来专门处理那些不须要用到UiAutomation的情况,比方下面的isScreenOn方法就不须要用到UiAutomation,而是直接用PowerManager服务来推断当前屏幕是否是打开的:
/*     */   public boolean isScreenOn()
/* */ {
/* 111 */ IPowerManager pm = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
/* */
/* 113 */ boolean ret = false;
/* */ try {
/* 115 */ ret = pm.isScreenOn();
/* */ } catch (RemoteException e) {
/* 117 */ Log.e(LOG_TAG, "Error getting screen status", e);
/* 118 */ throw new RuntimeException(e);
/* */ }
/* 120 */ return ret;
/* */ }
 

作者

自主博客

微信

CSDN

天地会珠海分舵

http://techgogogo.com

服务号:TechGoGoGo

扫描码:

http://blog.csdn.net/zhubaitian


UiAutomator源代码分析之UiAutomatorBridge框架的更多相关文章

  1. UiAutomator源代码分析之获取控件信息

    依据上一篇文章<UiAutomator源代码分析之注入事件>開始时提到的计划,这一篇文章我们要分析的是第二点: 怎样获取控件信息 我们在測试脚本中初始化一个UiObject的时候一般是像下 ...

  2. UiAutomator源码分析之UiAutomatorBridge框架

    上一篇文章<UIAutomator源码分析之启动和运行>我们描述了uitautomator从命令行运行到加载测试用例运行测试的整个流程,过程中我们也描述了UiAutomatorBridge ...

  3. Kafka 源代码分析之log框架介绍

    这里主要介绍log管理,读写相关的类的调用关系的介绍. 在围绕log的实际处理上.有很多层的封装和调用.这里主要介绍一下调用结构和顺序. 首先从LogManager开始. 调用关系简单如下:LogMa ...

  4. UiAutomator喷射事件的源代码分析

    上一篇文章<UiAutomator源代码分析之UiAutomatorBridge框架>中我们把UiAutomatorBridge以及它相关的类进行的描写叙述,往下我们会尝试依据两个实例将这 ...

  5. Appium Android Bootstrap源代码分析之启动执行

    通过前面的两篇文章<Appium Android Bootstrap源代码分析之控件AndroidElement>和<Appium Android Bootstrap源代码分析之命令 ...

  6. Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...

  7. Android应用程序框架层和系统运行库层日志系统源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6598703 在开发Android应用程序时,少 ...

  8. 【Android开源项目分析】android轻量级开源缓存框架——ASimpleCache(ACache)源代码分析

    转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46379055 ASimpleCache框架源代码链接 https://github ...

  9. Android异步任务处理框架AsyncTask源代码分析

    [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 引言 在平时项目开发中难免会遇到异步耗时的任务(比方最常见的网络请求).遇到这样的问题.我 ...

随机推荐

  1. 混合硬盘的U310重装系统

    最早接触U310 是在半年前,那时候同学在用的就是U310,需要升级Windows 8 依照以往的经验,弄了一张Windows 8的启动U盘,当在选择磁盘的时候居然发现没有可选项!这个有点出乎意料…… ...

  2. bootstrap中的Tooltips工具提示的使用问题

    在使用bootstrap中的Tooltips时,官方文档中的实例代码若直接放在.container 或 .container-fluid类中时,四个button悬停之后会把button之间的margi ...

  3. 反射生成SQL语句

    public static int Reg(Model ml) { bool b = true; Visit vt = new Visit(); StringBuilder builder = new ...

  4. git 使用笔记

    git操作: git checkout 分支名称 // 切换分支git branch -a // 查看分支信息和当前分支 git pull // 将服务器所有代码下载到本地git merge orig ...

  5. 【整理】--VC 编译整理

    .h用于编译阶段的审核,如在math.h中有函数声明:int abs(int);但是在使用中写为#include <math.h>...abs(3,5);编译器阶段就会检测出错误. .dl ...

  6. Linux下which、whereis、locate、find命令的区别

    我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索.这些是从网上找到的资料(参考资料1),因为有时很长时间不会用到,当要用的时候经常弄混了,所以放到这里方便使用. w ...

  7. IIS 7.5 + asp.net MVC4 设置路由处理URL请求

    使用asp.net MVC4开发的网站,在本地的VS012环境下运行,一切正常.但当发布到Windows 2008 R2(IIS7.5 + Framework4.5)上时,访问相关网页时,出现有下面的 ...

  8. C#设计模式——单件模式

    一.为何需要单件模式 需求 我们开发了一个大型的项目,其中存在许多的工具类.但是其中很多的工具类我们并不是经常使用得到,甚至 一次都不会使用.但是这些工具类都是静态的类,会消耗很多的内存,即使一次都不 ...

  9. solr与.net系列课程(一)solr的安装与配置

    不久之前开发了一个项目,需要用到solr,因为所以在开始再网上查找资料,但是发现大部分的资料都是很片面的,要么就是只讲解solr如何安装的,要么就是只讲解solr的某一个部分的,而且很多都是资料都是一 ...

  10. SpringMVC关于json、xml自动转换的原理研究[附带源码分析]

    目录 前言 现象 源码分析 实例讲解 关于配置 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.c ...