UiAutomator 打造专属 uiautomatorviewer

JoeJoe · 2016年04月12日 · 最后由 somedisappoint 回复于 2020年03月18日 · 3098 次阅读

打造专属 uiautomatorviewer,先看下成果展示:


看了 testerhome 网站《由 uiautomator 二次开发得到的启发以及完善》https://testerhome.com/topics/3048 ,感概真是相当棒的 idea。感到不足的地方是生成的脚本为啥不弄个可视化的界面展示出来,而且没有细化到获取选中的控件的 id,text,content-desc 和 class 去生成相对应的脚本,如果在右键菜单进行一些操作后刷新界面,那就更棒了!
带着这个思路,我决定去学习 uiautomatorviewer 的源码,并决定打造属于自己的 uiautomatorviewer,定了开发目标:

1.桌面端 uiautomatorviewer 获取界面,在界面加入简单操作并反馈至手机,部分操作亦刷新 viewer 界面,减少手动操作手机次数。
2.操作过程结合获取的元素生成简单自动化脚本,帮助提高书写代码的效率。

在工作之余大概花了 4 天的时间学习和开发完成,开发中途,周五大概完成了 80%,拿给了斌辉和温力同学看看,斌辉和温力同学都提出了相同的一个问题:控件的 id 或 text 或 content-desc 或 class 相同,能不能区分选中的控件是第几个?就是控件的 instance 问题,uiautomatorviewer 没有 instance 属性只有 index 属性。真是英雄所见略同,于是周末又花了半天的时间去研究下多叉树的遍历并开发出了获取 instance,自己的思路大体是这样的:

层次遍历多叉树,到选中的节点处截止,在这些遍历到的节点中,如果这些节点包含选中节点的某一属性(id 或 text 或 content-desc 或 class),则 instance + 1。

本来这个思路挺好的,可是开发遍历过程中写的函数给我返回的这些节点只有父节点,调了好久没成功,于是改变思路分两步走:

1.遍历整个界面所有节点,保存起来。
2.在所有节点中找出选中节点的前面的节点,如果这些节点包含选中节点的某一属性(id 或 text 或 content- desc 或 class),则 instance + 1。

开发准备:
1.uiautomatorviewer 源码
2.swt 开发http://www.cnblogs.com/xing901022/p/4098368.html
3.度娘

大概弄清楚 uiautomatorviewer 的原理后,进行改写 uiautomatorviewer,实施方案:

1.主窗口类 UiAutomatorViewer,改写为单例模式,添加获取 root 节点和当前节点的私有变量 UiAutomatorModel uModel,在回调函数 setModel 对 uModel 赋值,我当时这样想这样做的目的是无论我在哪个类下我都能刷新 viewer 和获取当前 root 节点和选中节点。


主窗口类


改为单例模式,添加私有变量 uModel


回调函数赋值 uModel

2.swt 的控件主要在 UiAutomatorView 扩展,请看 swt 开发或问度娘,大体扩展如下

3.遍历整个界面多叉树,在 BasicTreeNode 扩写,本来我写了第一个思路的函数老调试不成功,改写成第二个思路,请看代码,如果你有优化方案请告诉我。

遍历完后:

共收到 22 条回复 时间 点赞

很赞.希望可以使用 Markdown 排版.

大赞!能共享改造后的 uiautomatorviewer.jar 成本,就更好了。
抱歉,我对 java 不熟,只能做伸手党啦。

很赞~~~idea 不错

@zengjunzhou 求问如果是自己改的时候,怎么进行调试?也是当作一般的 java 工程吗
另外想问问@xuxu 分享的那个源码,要怎么下载,是只需要下载 uiautomatorviewer 的部分就可以了吗

@snowmaster 点源码页面的 “tgz” 下载

#6 楼 @xuxu 感谢~ 之前懒得切系统了,还好 win 下 rar 能解压

@xuxu
来顶同事好贴。
再次惭愧自己的动手能力。

作的手艺不错。

大神厉害 开启膜拜模式

楼主,想问下你获取 activity 会不会卡一会儿才能获取到?
我点击 device sreenshot 后,会反复执行几十次 adb 命令(不知道哪里的原因。。),导致会卡一下

刚刚发现原来是处理 xml 时,会遍历界面上所有的控件,每次遍历的时候都会执行 adb 命令查询 activity。。所以不能像处理 xpath 那样改了,没必要写到 Uinode 里面了

匿名 #14 · 2016年04月13日

能分享共同研究一下吗?

  • 楼主,想问下你的输入框输入文本是怎么处理的?adb 不支持中文,而且还有手机输入法的干扰。。当然这个不用 adb 输入也没问题,因为自动生成代码脚本那块是没问题的
  • 获取同 class 或者 id 控件中是第几个这个问题,我的做法是直接获取选中的节点的父节点,然后遍历父节点的所有子节点(即选中的节点同级的所有节点),然后统计在选中节点前的节点中同 class 或者 id 控件个数

请问能识别 webview 吗

我使用源码中 UiAutomatorHelper.takeSnapshot() 刷新界面,得等待 6S 左右的时间才能刷新完成,不知道各路大神有没有什么优化思路呢??

#15 楼 @niuniudd 大侠能把你的刷新部分代码贴出来吗 菜鸟连刷新都还没搞定呢..

测试小白,求 uiatuomator 源码一份,谢谢...

棒棒哒,么么

请问一下,怎么获取当前页的 activity

请问下楼主,能不能分享下源码?
关于 swt,我自己也重新编译了 Uiautomatorviewer,可是一直报如下的错误
Exception in thread "main" java.lang.UnsatisfiedLinkError: no swt-cocoa-3550 or swt-cocoa in swt.library.path, java.library.path or the jar file
at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
at org.eclipse.swt.internal.Library.loadLibrary(Unknown Source)
at org.eclipse.swt.internal.C.(Unknown Source)
at org.eclipse.swt.internal.cocoa.NSThread.isMainThread(Unknown Source)
at org.eclipse.swt.graphics.Device.(Unknown Source)
at org.eclipse.swt.widgets.Display.(Unknown Source)
at org.eclipse.swt.widgets.Display.(Unknown Source)
at org.eclipse.swt.widgets.Display.getDefault(Unknown Source)
at org.eclipse.swt.widgets.Shell.(Unknown Source)
at org.eclipse.swt.widgets.Shell.(Unknown Source)
at org.eclipse.jface.window.Window.createShell(Window.java:487)
at org.eclipse.jface.window.Window.create(Window.java:430)
at org.eclipse.jface.window.Window.open(Window.java:790)
at com.android.uiautomator.UiAutomatorViewer.main(UiAutomatorViewer.java:90)
按照网上的说法换了好几次 swt 一直没解决,求帮忙

雪怪 [该话题已被删除] 中提及了此贴 08月19日 16:31
雪怪 uiautomatorviewer 功能扩展实践 中提及了此贴 12月06日 22:35

能不能求一份源码研究一下,小白实在是自己写不出来

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册