Uiautomator-获取控件原理

  • 如何获取控件信息

我们在测试脚本中初始化一个UiObject的时候通常是像以下这个样子:

 

那么这个过程发生了什么呢?这就是我们接下来要说的事情了。

1. 获取控件信息顺序图

这里依然是一个手画的不规范的顺序图,描述了UiObject尝试获得一个控件的过程中与相关的类的交互,这些类的关系在《UiAutomator源码分析之UiAutomatorBridge框架》中已经进行了描述。

这里整一个过程并不复杂,简单说明下就这几点:

  • UiObject对象几经周折通过不同的类最终联系上UiAutomation,然后通知UiAutomation对象它想取得当前活动窗口的所有元素的AccessibilityNodeInfo类型的根节点
  • AccessibilityNodeInfo代表了屏幕中控件元素的一个节点,同时它也拥有一些成员方法可以以当前节点为基础来获得其他目标节点。可以把屏幕上的节点想像成是通过类似xml的格式组织起来的,所以一旦知道根节点和由选择子UiSelector指定的目标控件信息,我们就可以遍历整个窗口控件
  • QueryController对象获得Root Node之后,就是调用tranlateCompoundSelector这个方法来遍历窗口所有控件,直到找到选择子UiSelector指定的那个控件为止。
  • 注意一个AccessibilityNodeInfo只代表一个控件,遍历的时候一旦需要下一个控件的信息是必须要再次通过UiAutomation去获取的。

2.触发控件查找真正发生的地方

在我没有去分析uiautomator的源代码之前,我一直以为空间查找是在通过UiSelector初始化一个UiObject的时候发生的:

UiObject appsTab = new UiObject(new UiSelector().text("Apps"));


这让我有一种先入为主的感觉,一个控件对象初始化好后应该就已经得到了该控件所代表的节点的所有信息了,但看了源码后发现事实并非如此,以上所做的事情只是以一定的格式准备好UiSelector选择子而已,真正触发uiautomator去获取控件节点信息的是在触发控件事件的时候,比如:

appsTab.click()

我们进入到代表一个控件的UiObject对应的操作控件的方法去看下就清楚了,以上面的click为例:

 

正式290行的调用触发uiautomator去调用UiAutomation去获取到我们想要的控件节点AccessibilityNodeInfo信息的。

 

 

3.获得根节点

下面我们看下uiautomator是怎么去获取到代表窗口所有控件的根的Root Node的,我们进入UiObject的findAccessibilityNodeInfo这个方法:

UiObject对象会首先去获得一个QueryController对象,然后调用该对象的findAccessibilityNodeInfo同名方法:

 

这里做了两个重要的事情:

 

 

  • 150行:通过调用getRootNode来获得根节点,这个就是我们这个章节的重点
  • 158行:通过调用translateCompoundSelector来根据用户指定的UiSelector格式从上面获得根节点开始遍历窗口控件树,以获得我们的目标控件

好,我们继续往下进入getRootNode:

 

172调用的是UiAutomatorBridge对象的方法,通过我们上面的几篇文章我们知道UiAutomatorBridge提供的方法大部分都是直接调用UiAutomation的方法的,我们进去看看是否如此:

果不其然,最终简单明了的直接调用UiAutomation的getRootInActiveWindow来获得根AccessibilityNodeInfo.

 

4.遍历根节点获得选择子UiSelector指定的控件

如前所述,QueryController的方法findAccessibilityNodeInfo在获得根节点后下来做的第二个事情:

  • 158行:通过调用translateCompoundSelector来根据用户指定的UiSelector格式从上面获得根节点开始遍历窗口控件树,以获得我们的目标控件

里面的算法细节我就不打算去研究了,里面考虑到选择子嵌套的情况,分析起来也比较费力,且了解了它的算法对我去立交uiautomator的运行原理并没有非常大的帮助,我只需要知道给定一棵树的根,然后制定了我想要的叶子的属性,那么我遍历整棵树肯定是可以找到我想要的那个/些满足要求的控件的。大家由兴趣了解其算法的话还是自行去研究吧。

 

5.最终还是通过坐标点来点击控件

上面UiObject的Click方法通过UiAutomation这个高大上的新框架获得了代表我们目标控件的AccessibilityNodeInfo后,跟着是不是就直接调用这个节点的Click方法进行点击了呢?其实不是的,首先AccessibilityNodeInfo并没有click这个方法,我们继续看代码:

从395行可以看到,最终还是把控件节点的信息转换成控件的坐标点进行点击的,至于怎么点击,大家可以参照上一篇文章,无非就是通过建立一个runnable的线程进行点击事件的注入了

 

参考博客:https://blog.csdn.net/zhubaitian/article/details/40581369

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值