如何使用和调试 android UIAutomator
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用和调试 android UIAutomator相关的知识,希望对你有一定的参考价值。
参考技术A (1):Google在sdk4.0以后提供了一个自动化解决方案uiautomator:
优点:可以跨应用了;这可是亲生的;
缺点:必须sdk4.0以上版本;要想实现的好,最好有开发配合;java项目编译为jar后需要push到手机才能运行,也就是说必须打印日志暴力调试。
Appium基于android InstrumentationFramework和UIAutomator,也就是说这个工具是可以跨应用的。说远了,好吧,为了更容易理解appium的使用
(2)uiautomator的使用方法:
应该有android-sdk吧,升级到4.0以上,进入目录android-sdk\tools,会看到两个文件:
traceview.bat 和 uiautomatorviewer.bat,这俩文件想起了monkeyrunner了吧,是的,traceview.bat就对应于hierarchyviewer.bat,用来查看程序的ui界面的,通常也是使用管理员权限启动的。
好了,现在用eclipse创建一个java project,是的,没看错,是java project不是android project,添加引用:
在project.properties中内容为:
# Project target.
target= android-16
这里的android-16需要和之前的android.jar和uiautomator.jar位置相一致。
(3)代码参考:
package com.uia.example.my;
import org.apache.http.util.EncodingUtils ;
import android.graphics.Bitmap ;
import android.graphics.BitmapFactory ;
import android.graphics.Rect ;
import android.os.Environment;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import com.android.uiautomator.core. UiSelector ;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class TAppWorkAssistV1 extends UiAutomatorTestCase
public String sLog ;
public File fout = null ;
public FileOutputStream outStream = null ;
public void write2file(String filename,String sData)
String sLog= "" ;
// 初始化日志文件
if (Environment. getExternalStorageState ().equals(Environment.MEDIA_MOUNTED ))
sLog = Environment. getExternalStorageDirectory().getAbsolutePath();
try
fout = new File(sLog,filename);
outStream = new FileOutputStream( fout , true ); // 此处的 true 是append
sData=sData + "\n" ;
outStream .write(sData.getBytes());
outStream .flush();
outStream .close();
fout = null ;
catch (Exception e)
e.printStackTrace();
else
System. out .println( " 该手机没有 SD 卡 " );
public void testDemo() throws UiObjectNotFoundException
//1. 启动 app
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject( newUiSelector().description( "Apps" ));
allAppsButton.clickAndWaitForNewWindow();
UiObject appsTab = new UiObject( new UiSelector().text( "Apps" ));
appsTab.click();
UiScrollable appViews = new UiScrollable( newUiSelector().scrollable( true ));
UiObject settingsApp = appViews.getChildByText( newUiSelector().className(android.widget.TextView. class .getName()), "Efilm" );
settingsApp.clickAndWaitForNewWindow();
//2. 进入主界面
System. out .println( "into main view" );
System. out .println(getUiDevice().waitForWindowUpdate("com.eshore.efilm" , 60000));
System. out .println( "intoed main view" );
UiObject tv1 = new UiObject( new UiSelector().text( " 影院 " ));
tv1.click();
//3. 点击影院
UiObject oyy= new UiObject( new UiSelector().description("cinema_row" ));
System. out .println( "wait yingyuan come out" );
oyy.waitForExists(60000);
System. out .println( "yingyuan come out" );
oyy.clickAndWaitForNewWindow();
System. out .println( "click yingyuan" );
//4. 场次
UiObject occ= new UiObject( new UiSelector().description("LinearLayout10" ));
System. out .println( "wait changci come out" );
oyy.waitForExists(60000);
System. out .println( "changci come out" );
occ.clickAndWaitForNewWindow();
System. out .println( "click changci" );
//5. 座位
UiObject oseat= new UiObject( new UiSelector().description("cinema_shows_list_item" ).index(0).childSelector( newUiSelector().description( "LinearLayout10" )));
System. out .println( "wait seat come out" );
oseat.waitForExists(5000);
int h=getUiDevice().getDisplayHeight();
int w=getUiDevice().getDisplayWidth();
System. out .println( "(h/2,w/2)=" +h/2+ "," +w/2);
getUiDevice().click(h/2,w/2);
//System.out.println("seat count:"+String.valueOf(oseat.getChildCount()));
//System.out.println("seat getText:"+ oseat.getText());
// 截座位图
Process process;
try
process = Runtime. getRuntime ().exec( "screencap /mnt/sdcard/EfilmFailSnapShot01.png" );
try
process.waitFor();
catch (InterruptedException e) // TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
//takeScreenShots("EfilmSeatSnapShot");
(4)执行:
这个例子是随便写的,可能不够严谨。大体就这么个情况吧。下一步就是编译执行了,先插上手机usb接口,然后打开cmd,执行:
找到SDKID,也就是android create中的-t参数:
cd C:\ PROGRAM\android-sdk\tools
android list
找到t参数的值以后:
cd C:\ PROGRAM\android-sdk\tools
android create uitest-project -n TAppWorkAssistV1 -t 25 -p C:\android自动化\Tv2.0\TestSetting
cd C:\android自动化\Tv2.0\TestSetting
ant build
cd C:\android自动化\Tv2.0\TestSetting\bin
adb push TAppWorkAssistV1.jar /data/local/tmp/
adb shell uiautomator runtest TAppWorkAssistV1.jar -c com.uia.example.my. TAppWorkAssistV1
(5)需要注意的:
-n TAppWorkAssistV1:类名
-p: 项目所在目录
Ant build 把这个类编译成一个jar包:TAppWorkAssistV1.jar
然后把jar包push到手机上,调用执行这个类就可以了
大致是这么个步骤,不过有一个非常重要的细节,就是如果需要更省心,就最好把界面元素,无论动态的还是布局文件中的,都加上content-description属性,并保证唯一性,根据:
UiSelector:description(String desc)
Set the search criteria to match thecontent-description property for a widget.
那就可以统一只使用这一个引用界面元素的方法就行了,就不用去想方设法利用其它的属性来引用了。
如何使用Android真机进行调试
如何使用真机调试应用程序
在开发android应用程序的时候,有时候开发不得不采用真机调试,原因很简单,因为模拟器暂时无法支持模拟一些硬件设备,而重力感应一类的开发效果更需要用真机调试。当然,采用真机调试要比模拟器快很多,模拟器不仅占PC的资源,而且运行久了会变得相当的迟钝。
采用android真机调试的最需要解决的是真机与电脑连接的问题,一旦成功连接之后,其实与模拟器调试就没什么差别了,只需要在运行Android Project时选择真机即可。在Android2.3之前,由于Android真机无统一的标准,机型众多并且各自的USB驱动都不一样,因此需要去各自的手机生产厂商官方网站去下载并安装对应正确的usb的驱动(或者说是ADB Interface Driver),不过在新版本的SDK中,由google提供了新的usb驱动解决方案,该驱动存放在”%android_sdk_path%/google-usb_driver”文件夹,一般来说目前市面上流行的Android系统机型都能够被支持,因此简化了USB驱动安装,我们优先采用此驱动进行安装,实在无法成功安装再去下载由真机生产厂商提供的驱动。这里以笔者在win7使用的MotorolaMilestone为例。
第一步:将我们开发所用的Android真机的USB调试功能打开(打开方法为Settings(设置)àApplications(应用程序)àDevelopment(开发)à勾选USB debugging(USB调试)),然后通过usb连接线连接到开发所用的PC上,由于是在没有安装usb驱动的情况下进行连接,系统会发现新硬件并且尝试通过windows update在互联网上搜索驱动进行安装:
第二步:由于通过windows update查找驱动会耗费非常长的时间并且需要互联网支持而且不一定能够成功找到,因此我们点击下方的“跳过从Windows Update获得驱动程序软件”跳过搜索:
第三步:关闭自动安装后,通过右键点击“计算机”(XP-我的电脑)选择“管理”进入到计算机管理界面,点击左边的“设备管理器”进入到设备管理界面,此时我们会发现一个带有黄色感叹号标志的硬件设备(如图中所示,位于其他设备分支下),即“Motorola ADB Interface”,这代表着该设备缺少驱动程序支持,从名称上看很显然这个设备就是我们usb调试需要的支持设备:
第四步:安装该设备的驱动程序,右键点击“Motorola ADB Interface”选择“更新驱动程序软件”,弹出如下图所示框体:
第五步:正如前面所说,由于我们的SDK中已经存在了google提供的usb驱动程序,因此我们选择第二项“浏览计算机以查找驱动程序软件”,进入到下一对话框,在这里点击浏览,选中目录“%android_sdk_path%/google-usb_driver”,例如这里是使用的D:\study\programfiles\android-sdk-windows-r8\google-usb_driver路径,勾选上下方的“包括子文件夹”,点击下一步:
第六步:在上一步最后点击下一步按钮后,系统会开始在我们设置的文件夹下查找驱动程序软件并进行安装,这一步需要2分钟左右的时间,请耐心等待:
第七步:等待一段时间后,不出意外,系统将会提示“已经成功地更新驱动程序软件”,如下图,如果这一步失败,也不用慌张,可能是google提供的这种驱动暂时不能支持你所使用的真机,这时就需要到你所使用机器的生产厂商的官方网站去下载驱动程序软件,然后重复前面的步骤,只需要在第五步时设置驱动程序软件路径时定位到你所新下载的特定驱动程序的存放路径即可,附件还提供了两款常用USB驱动程序,即motorola和HTC的usb驱动。
第八步:驱动程序安装完成后,此时再到设备管理器中查看,可以发现带黄色感叹号的“Motorola ADB Interface”设备已经消失了,取而代之的是在Android Phone分支下的“Android Composite ADB Interface”设备,这里再提到一点,如果是使用的Motorola的驱动程序的话,这里可能就是显示的“Motorola ADB Interface”了:
第九步:虽然前面系统已经提示了驱动程序安装正确,如果才能确定PC已经识别
Android真机并且正确地建立了连接呢?很简单,首先点击开始->运行,输入cmd:
第十步:在弹出的命令提示符界面中使用命令adb devices查看设备(adb命令所对应的应用程序存放在%android-sdk-path%\platform-tools路径下,这里能够在任意路径下使用adb是因为笔者PC机的环境变量中加入了该路径,如果没有设置环境变量则需要首先定位到%android-sdk-path%\platform-tools路径,否则会提示adb不是一个有效的命令,如下图所示,返回了一个编号为04038B6005021006的device(代表真机),这就代表真机已经成功地与PC建立起连接了,如果PC上也运行了模拟器,会发现不只一条的记录,模拟器的类型是emulator:
那么,如何在调试的时候选择真机呢?通常,当我们点击运行一个Android Project时,它的默认行为是由eclipse自主选择一个设备进行应用程序的安装、运行,如果想要人工自主地选择调试设备,可以在对应Project的Run Configuration中进行设置,如图:
点击Run Configuration后,将会弹出配置界面:
该界面左边一侧的栏目中是现在存在的一些可配置的应用程序,在左边选择待调试的应用程序,然后在右边单击Target选项卡,选择Manual(手动)即可,需要注意的是,好像目前eclipse在这里存在一个小问题(有可能是笔者自身的操作问题),就是新建的一个项目在第一次编译运行过之前,该项目对应的应用程序不会出现在左边的应用程序列表中,因此不能对其进行设置,也就是说第一次Run时只能使用Automatic的方式由eclipse指定目标设备。不过这种情况影响并不大,假如eclipse此时自己启动了一个模拟器来作为目标,可以立即关闭模拟器终止该操作,之后该项目应用程序就会出现在列表中可以配置为Manual了:
配置成Manual方式后,在Run一个Android Project的时候将会弹出一个选择框用于选择设备,如下:
可以看到我们的真机出现在了正运行的设备列表中,通过选中该项点击OK或者直接双击它就可以将应用程序安装到真机上进行调试了,当然,如果你需要的是模拟器调试,选中“Launch a new Android Virtual Device”然后选择需要启动的模拟器(列表中是已经建立的模拟器,也可以新建模拟器)就可以了。
引自:http://wenku.baidu.com/link?url=RxOBMJWhKafHVHA5XjWE1m7v_obLRfoAGe8Zw9Ck_8hdKb5-0u3r6FXsNSfcW34rCk3JIMIhp4XSoEfArae7V18074IDYaVmx3owsmY1lxK
以上是关于如何使用和调试 android UIAutomator的主要内容,如果未能解决你的问题,请参考以下文章