Uiautomator ——API详解(转载http://www.cnblogs.com/by-dream/p/4921701.html)

转载来源:

简单的例子



  以一个简单的例子开始吧。我们完成一个 " 打开QQ,进入QQ空间,然后退出 " 的case。

  代码如下:

package QQ;

import java.io.IOException;

import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;

public class Test_qq extends UiAutomatorTestCase
{
    public void testDemo() throws IOException, UiObjectNotFoundException {

        // 启应用
        Runtime.getRuntime().exec("am start com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity");
        sleep(3000);

        // 点击 "动态" tab
        UiDevice device = getUiDevice();
        int height = device.getDisplayHeight();
        int width = device.getDisplayWidth();
        device.click(width -50, height-50);
        sleep(1000);

        // 点击 "好友动态" 按钮
        UiObject obj_1 = new UiObject(new UiSelector().description("点击进入好友动态"));
        obj_1.click();
        sleep(2000);

        // 点击 左上角返回 "动态"按钮
        UiObject obj_2 = new UiObject(new UiSelector().resourceId("com.tencent.mobileqq:id/ivTitleBtnLeft"));
        obj_2.click();
        sleep(1000);

        // 点击菜单键
        device.pressMenu();
        sleep(1000);

        // 点击退出qq
        UiObject obj_3 = new UiObject(new UiSelector().text("退出QQ"));
        obj_3.click();
        sleep(1000);

        // 点击确定
        UiObject obj_4 = new UiObject(new UiSelector().text("确定"));
        obj_4.click();
    }
}

  脚本的运行效果如下:

代码详解



  针对上面的例子的代码,我对每一句代码都做个详细的解释吧。

  第一部分:启动应用

  

  exec() 这个函数的意思,相当于是在你在输入adb shell 命令后,在Android手机系统的命令行下运行。所以上面这句话的意思和我们打开cmd框输入" adb shell am start *** " 是一样的的效果。

  一般来说我们做App的自动化的时候,第一步都是把App打开,这个am start命令的就可以帮我们实现,类似与Monkeyrunner API中的startActivity() 函数。

  第二部分:点击 “动态” tab

     

  UiDevice对象会在API部分详细讲解,它是一个我们在Uiautomator中经常使用的一个对象。

  这里我们首先用它获取到当前手机的宽和高的像素。然后观察到 “动态” tab位于右下方,因此在取得右下角的坐标点后,又进行了一个大概的坐标变化(这里为了简单只是向左和向上移动了50像素,如果要精确的可以进行等比转化),然后点击该坐标。

  这里之所以用点击坐标的方法,一方面是因为这个控件Uiautomator不支持用API获得实例(上一节所说的NAF Nodes,如下图),另一方面也是想说明在一些控件没有固定的id、text和desc的时候,我们应该怎么处理。

  

  第三部分:点击 “好友动态”

  

  要想操作一个控件(例如),首先得获得一个UiObject对象,而UiObject对象可以通过UiSelector来构造,而UiSelector可以根据控件的idtextcontent-desc来进行构造,这里就是用content-desc来构造。

  

  如上图用 uiautomatorviewer 查到该控件的 content-desc 的内容是 “点击进入好友动态” ,因此我们就可以通过代码中的方法来得到UiObject对象了,然后调用click() 方法来达到点击效果。

  

  第四部分:点击左上角返回按钮

  

  同第三部分的方法,找到id后直接获得到UiObject对象,进行点击。

  第五部分:点击菜单键

  

  UiDevice 可以模拟点击home、back、menu 这三个键,代码应该大家都懂的怎么变化了吧。

  第六部分:退出

  

  这一部分也是先通过获取出控件属性中的text值,然后构造出UiObject对象,完成点击。

  以上部分内容就是整个操作QQ这个小例子的全部代码讲解,看完之后对写Uiautomator代码有了更进一步的了解了吧。接下来写看看还有哪些API可以支持我们做更多的事情。

API 列举



UiDevice

  概述:

    UiDevice用与访问关设备状态的信息,也可以使用这个类来模拟用户在设备上的操作。可以通过下面的方法得到实例:

    UiDevice mdevice = getUiDevice();

  摘要:

函数返回值 函数体 说明 实例
boolean click(int x, int y)     模拟用户在指定位置点击  mdevice.click(200, 300)  点击屏幕的200,300坐标处
String  getCurrentActivityName()  获得的是应用程序在桌面上显示的名字  例如,在qq首页得到的是“QQ”,在微信登录页得到的是“微信”,注意,这个得到的不是Activity的名字
String  getCurrentPackageName()  获得当前显示的应用程序的包名  例如,在微信启动的时候,获得的是“com.tencent.mm”
int  getDisplayHeight()  获得当前设备的屏幕分辨率的高  例如,我的手机1920*1080,得到的是 1920
int  getDisplayWighth()  获得当前设备的屏幕分辨率的宽  例如,我的手机1920*1080,得到的是 1080
boolean  isScreenOn()  判断手机当前是否灭屏  当手机灭屏的时候,得到是“false”,手机亮屏,得到的是“true”
void  wakeUp()  点亮当前屏幕  调用后,相当于按下了电源键,如果手机设置了滑动锁屏,滑动锁屏还是在的,不会自动解开
boolean  pressBack()  点击back键  
boolean  pressHome()  点击home键  
boolean  pressMenu()  点击menu键  
boolean  pressKeyCode(int keyCode)  利用keycode值模拟一次按下事件  例如,需要按下数字1 数字1的keycode是 KEYCODE_NUMPAD_1,更多keycode可以在 http://developer.android.com/intl/zh-cn/reference/android/view/KeyEvent.html进行查询
boolean  swipe(int startX, int startY, int endX, int endY, int steps)  用指定的步长,从A点滑动B点  例如,需要从(10, 10)点用两步滑动到(100, 200)点,则需要mdevice.swipe(10, 10, 100, 200, 2)
boolean  takeScreenshot(File storePath)  截取当前屏幕,保存到文件  例如,File files = new File("/sdcard/res.jpg"); mdevice.takeScreenshot(files); 即可将截图保存到sd卡中了。

UiSelector

  概述:

    按照一定的条件(例如控件的text值,资源id),定位界面上的元素。UiSelector对象的最终目的是去构造一个UiObject对象。

  摘要:

    1、根据text构造:

函数返回值 函数体 说明 用法
UiSelector text(String text) 根据“控件text属性的内容”构造出UiSelector对象 例如,一个控件text的值是“发现”,UiSelector s = new UiSelector().text("发现");
UiSelector textContains(String text) 根据“控件text属性包含的内容”构造出UiSelector对象 同上例子:UiSelector s = new UiSelector().textContains("现");
UiSelector textMatches(String regex)  根据“控件text属性正则表达式的内容”构造出UiSelector对象 正则表达式语法参考网上资料即可。
UiSelector textStartsWith(String text) 根据“控件text属性开始的内容”构造出UiSelector对象 同上例子:UiSelector s = new UiSelector().textStartsWith("发");

      比较常用,准确度也比较高,中文查找的时候,如果遇到 “UiOjbectNotFoundException” 的时候,记得把项目的编码格式改为utf-8。

    2、根据description构造:

UiSelector description(String desc) 根据“控件content-desc属性的内容”构造出UiSelector对象
UiSelector descriptionContains(String desc) 包含**
UiSelector descriptionMatches(String regex) 正则
UiSelector descriptionStartsWith(String desc) 以**开始

      同text的用法基本一致,也是比较靠谱的一种方式。

    3、根据资源id:

UiSelector resourceId(String id) 根据资源id获取对象,例如:UiSelector s = new UiSelector().resourceId("com.tencent.mm:id/b8m")
UiSelector resourceIdMatches(String regex) 根据资源id的正则表达式获取对象

    4、根据类:

      UiSelector className(String  className):

        根据控件的类名来找到UiSelector对象。

          

        但是呢?因为一般Android布局的时候,同样的控件类名都是一样的。

        因此我在微信的登录界面调用: UiSelector s = new UiSelector().className("android.widget.TextView") 这句话,它得到的就是我左上开始算第一个class名称为“android.widget.TextView”的控件。

      

      UiSelector instance (int instance):

        上面提到的假如我们想获取屏幕上电话号码的那个TextView使用这样方法,就可以使用instance:

            UiSelector s = new UiSelector().className("android.widget.TextView").instance(1);

    

      UiSelector index(int index):

        用法和上面的instance差不多,谷歌的原文说这个方法是unreliable的,推荐使用instance方法。

          

      UiSelector childSelector(UiSelector selector):

        有的时候假如子控件不好获得,而其父控件比较好获得的时候,我们通常采用这样的方式,例如下面:

        

      我们目前选中的是LinearLayout,这个Android中的一种布局,它的里面嵌套了两个控件,一个是ImageView,另一个是EditText。这们这里就通过LinearLayout这个控件找到它的子控件。

        很明显,父控件id已经给定。我们先得到父控件:UiSelector s_p = new UiSelector().resourceId("com.tencent.mm:id/axj");

        其次 UiSelector s_c= s_p.childSelector( new UiSelector().className("android.widget.EditText") );

        在它的父控件的childSelector方法中传入一个带有一定特征的UiSelector对象,即可得到子控件,这里 s_c 就是输入框的UiSelector对象。

      

      UiSelector fromParent(UiSelector selector):

        有的时候父控件也不好获得,而是同级的控件(同属一个parent)比较好获取,那么使用这样方法,还拿上面的举例:

        我们先得到EditText的UiSelector对象:UiSelector s1 = new UiSelector().resourceId("com.tencent.mm:id/axc");

        得到和它同样一个父控件的ImageView的UiSelector对象:UiSelector s2 = fromParent( new UiSelector().className("android.widget.ImageView") );

    

    5、根据特有属性:

UiSelector checked(boolean val) 根据是否可check来构造出UiSelector对象
UiSelector chickable(boolean val)  
UiSelector enabled(boolean val)  
UiSelector focusable(boolean val)  
UiSelector longClickable(boolean val)  
UiSelector scrollable(boolean val)  
UiSelector selected(boolean val)  

      举个简单的例如,假如当前的界面,只有一个checkbox是勾选状态,你就可以这样得到:UiSelector s2 = new UiSelector().checked(true)

        

UiCollection  

  概述: 用的不多,直接参考文档   

  摘要:   http://android.toolib.net/tools/help/uiautomator/UiCollection.html

UiScrollable

  概述:  用的不多,直接参考文档   

  摘要:    http://www.cnblogs.com/by-dream/p/4921701.html

UiObject

  概述:可以理解为 直接操作界面ui元素的实例。

  摘要:


返回值


函数


void


ClearTextField()
在可以编辑处清除已经存在的文本内容


boolean


click()
执行单击


boolean


clickAndWaiForNewWindow(long timeout)
执行单击,等待窗口出现,等待时间参数中设置


boolean


clickAndWaiForNewWindow()
点击等待一个新窗口的出现,默认等待时间


boolean


clickBottomRight()
点击ui元素的右下方


boolean


clickTopLeft()
点击ui元素的左上方


boolean


exists()
检查ui 元素是否存在


Rect


getBounds()
返回ui元素的坐标值


UiObject


getChild(UiSelector selector)
通过参数中的对象,创建一个新的当前元素的子类ui元素的子类元素


int


getChildCount()
获取对象下子类ui元素数量


String


getContentDescription()
读取ui 元素的描述信息值


UiObject


getFromParent(UiSelector selector)
根据当前参数对象从父类元素获取子类信息


String


getPackageName()
读取Ui元素的包名称


final UiSelector


getSelector()
获取selector用作帮助调试


String


getText()
根据Ui元素获取文本值


Rect


getVisibleBounds()
返回ui元素的可视范围


boolean


isCheckable()
检查对象的checkable属性是否为true


boolean


isChecked()
检查对象的checked属性是否为true


boolean


isClickable()
检查对象的clickable属性是否为true


boolean


isEnabled()
检查对象的enabled属性是否为true


boolean


isFocusable()
检查对象的focusable属性是否为true


boolean


isFocused() 
检查对象的focused属性是否为true


boolean


isLongClickable() 
检查对象的longclickable属性是否为true


boolean


isScrollable() 
检查对象的scrollable属性是否为true


boolean


isSelected()
检查对象的selected属性是否为true


boolean


longClick()
长按对象


boolean


longClickBottomRight()
长按对象右下方


boolean


longClickTopLeft()
长按对象左上方


boolean


setText(String text)
ui对象中输入文字


boolean


swipeDown(int steps)
向下滑动steps个步长


boolean


swipeLeft(int steps)
往左滑动step个步长


boolean


swipeRight(int steps)
往右滑动steps个步长


boolean


swipeUp(int steps)
向上滑动steps个步长


boolean


waitForExists(long timeout)
等待对象出现


boolean


waitUntilGone(long timeout)
等待对象消失

时间: 2024-10-09 22:37:40

Uiautomator ——API详解(转载http://www.cnblogs.com/by-dream/p/4921701.html)的相关文章

Java 8 Streams API 详解

流式编程作为Java 8的亮点之一,是继Java 5之后对集合的再一次升级,可以说Java 8几大特性中,Streams API 是作为Java 函数式的主角来设计的,夸张的说,有了Streams API之后,万物皆可一行代码. 什么是Stream Stream被翻译为流,它的工作过程像将一瓶水导入有很多过滤阀的管道一样,水每经过一个过滤阀,便被操作一次,比如过滤,转换等,最后管道的另外一头有一个容器负责接收剩下的水. 示意图如下: 首先通过source产生流,然后依次通过一些中间操作,比如过滤

Android基础入门教程——8.3.16 Canvas API详解(Part 1)

Android基础入门教程--8.3.16 Canvas API详解(Part 1) 标签(空格分隔): Android基础入门教程 本节引言: 前面我们花了13小节详细地讲解了Android中Paint类大部分常用的API,本节开始我们来讲解 Canvas(画板)的一些常用API,我们在Android基础入门教程--8.3.1 三个绘图工具类详解 中已经列出了我们可供调用的一些方法,我们分下类: drawXxx方法族:以一定的坐标值在当前画图区域画图,另外图层会叠加, 即后面绘画的图层会覆盖前

Android基础入门教程——8.3.18 Canvas API详解(Part 3)Matrix和drawBitmapMash

Android基础入门教程--8.3.18 Canvas API详解(Part 3)Matrix和drawBitmapMash 标签(空格分隔): Android基础入门教程 本节引言: 在Canvas的API文档中,我们看到这样一个方法:drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) 这个Matrix可是有大文章的,前面我们在学Paint的API中的ColorFilter中曾讲过ColorMatrix 颜色矩阵,一个4 * 5 的矩阵

[转]Mahout推荐算法API详解

Mahout推荐算法API详解 Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeeper, Avro, Ambari, Chukwa,新增加的项目包括,YARN, Hcatalog, Oozie, Cassandra, Hama, Whirr, Flume, Bigtop, Crunch, Hue等. 从2011年开始,中国进入大数据风起云涌的时代,以Hadoop为代表的家族软件,占

Java 8 Stream API详解

Java 8 Stream API详解 一.Stream API介绍 Java 8引入了全新的Stream API,此Stream与Java I/O包里的InputStream和OutputStream是完全不同的概念,它不同于StAX对XML解析的Stream,也不同于Amazon Kinesis对大数据实时处理的Stream.Stream API更像具有Iterable的集合类,但行为和集合类又有所不同,它是对集合对象功能的增强,专注于对集合对象进行各种非常便捷.高效的聚合操作或大批量数据操

百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和DOM编程里的事件模型一样,百度地图API也提供了类似的事件机制.本文介绍了事件监听的添加和移除方法,this指针和事件参数的使用以及绑定事件监听函数中涉及的闭包问题,最后分享了一个用来增强地图API事件机制的开源项目. 事件添加和移除 我们最简单的事件开始,下面的代码示例给map对象添加了click事件的监听

[转]百度地图API详解之地图坐标系统

博客原文地址:http://www.jiazhengblog.com/blog/2011/07/02/289/ 我们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然需要一个转换过程,这个过程就叫做投影(Projection).在地球上我们通过经纬度来描述某个位置,而经过投影之后的地图也有自己的坐标系统,本篇文章就来详细介绍在百度地图API中涉及的各种坐标体系. 在百度地图API中,你需要了解如下坐标系: 经纬度:通过经度(longitude)和纬度(latitu

SDN 网络系统之 Mininet 与 API 详解

SDN 网络系统之 Mininet 与 API 详解 来源 https://www.ibm.com/developerworks/cn/cloud/library/1404_luojun_sdnmininet/ 更多资料 1. Mininet: http://mininet.org/ 2. Mininet wiki: https://github.com/mininet/mininet/wiki SDN 与 Mininet 概述 SDN 全名为(Software Defined Network)

079:【Django数据库】QuerySet API详解-filter、exclude、annotate

QuerySet API详解-filter.exclude.annotate: 在使用 QuerySet 进行查找操作的时候,可以提供多种操作.比如过滤完后还要根据某个字段进行排序,那么这一系列的操作我们可以通过一个非常流畅的 链式调用 的方式进行.比如要从文章表中获取标题为 123 ,并且提取后要将结果根据发布的时间进行排序,那么可以使用以下方式来完成: articles = Article.objects.filter(title='123').order_by('create_time')