android 模拟ua,Android R 给自家 UA 工具挖坑

Android R(SDK=30)系统执行 UiAutomator1.0 异常

最近 Android 发布了 AndroidStudio 3.6 稳定版,升级后明显能体验到好多细节的提升,最大的提升莫过于可以创建 Android R 预览版的模拟器了,并且模拟器可以设置多个尺寸的屏幕。Android R 的 xm6 模拟器可以直接运行 arm 架构的程序,以后开发过程中再也不用为测试机担忧了。但是在执行 uiautomator1 脚本时就存在了不兼容问题。

异常情况

但是在使用 Android R 模拟器进行开发工作中发现执行 UiAutomator1.0 脚本出现如下异常:

Warning: This version of UI Automator is deprecated. New tests should be written using

UI Automator 2.0 which is available as part of the Android Testing Support Library.

See https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html

for more details.

INSTRUMENTATION_STATUS: stream=

Test results for WatcherResultPrinter=Test run aborted due to unexpected exception: Failed resolution of: Landroid/test/RepetitiveTest;

java.lang.NoClassDefFoundError: Failed resolution of: Landroid/test/RepetitiveTest;

at com.android.uiautomator.testrunner.UiAutomatorTestRunner$WatcherResultPrinter.startTest(UiAutomatorTestRunner.java:297)

at junit.framework.TestResult.startTest(TestResult.java:168)

at junit.framework.TestResult.run(TestResult.java:119)

at junit.framework.TestCase.run(TestCase.java:129)

at com.android.uiautomator.testrunner.UiAutomatorTestRunner.start(UiAutomatorTestRunner.java:160)

at com.android.uiautomator.testrunner.UiAutomatorTestRunner.run(UiAutomatorTestRunner.java:96)

at com.android.commands.uiautomator.RunTestCommand.run(RunTestCommand.java:91)

at com.android.commands.uiautomator.Launcher.main(Launcher.java:83)

at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)

at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:396)

Caused by: java.lang.ClassNotFoundException: android.test.RepetitiveTest

... 10 more

Time: 0.039

OK (1 test)

INSTRUMENTATION_STATUS: shortMsg=Failed resolution of: Landroid/test/RepetitiveTest;

INSTRUMENTATION_STATUS_CODE: -1

异常触发流程

通过分析发现是因为找不到Landroid/test/RepetitiveTest类文件。那么分析一下堆栈信息看异常具体出现在哪里?

在执行 UiAutomator1.0 测试用例时,是在 UiAutomatorTestRunner 类中初始化测试资源并执行测试用例的。所以对异常堆栈信息的分析从 UiAutomatorTestRunner 类开始。

com.android.uiautomator.testrunner.UiAutomatorTestRunner.run(UiAutomatorTestRunner.java:96)源码如图,可以看到此处不存在异常行为,需要定位下一个堆栈信息

9683313892b018fd41551bfd59a4c87e.png

com.android.uiautomator.testrunner.UiAutomatorTestRunner.start(UiAutomatorTestRunner.java:160) 通过分析源码会发现是遍历执行测试用例时产生的异常,并且此处是

09535f760e6fe9d7f40e84612f62bf96.png

junit.framework.TestResult.startTest 仅仅调用了 WatcherResultPrinter#startTest 方法,所以需要继续定位异常原因

b4981e5c4587358ead5b3a9005c5af98.png

com.android.uiautomator.testrunner.UiAutomatorTestRunner$WatcherResultPrinter.startTest(UiAutomatorTestRunner.java:297)是真正触发异常的位置,可以看到第一次引用 android.test.RepetitiveTest 接口文件时产生了java.lang.NoClassDefFoundError:异常信息。

76b98bbff885812e682b79e43af278ca.png

定位问题原因

通过上述堆栈调用链发现触发异常时还没有执行测试用例,所以这个异常应该是出现在 framework 层面。由于缺失测试库导致的,查阅 Android R 行为变更,确认由于移除 android.test.base 库导致的问题,uiautomator1.0 使用该库加载并运行测试用例。

824b5d56b2ca8a99e582c8a3659f2578.png

对于采用 uiautomator1.0 的业务线需要提前进行技术适配。通过上文可以看到,在抛异常时程序已经初始化了 uiautomator1.0 测试环境,因此 Android R 是系统支持 uiautomator1.0 框架 API 的,我们需要通过 app_process 命令启动一个 java 进程,在 Java 进程内部初始化测试服务,然后初始化 uiautomator1.0 测试框架就能正常使用 uiautomator1.0 API 了,不过需要手动维护用例执行顺序,不能使用 junit3 测试框架特性。

想要了解 Uiautomator 执行原理可以参考Uiautomator 项目搭建与实现原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很好,关于设置Android WebView的UA为可切换的代码,我可以给你提供以下的示例代码: ```java WebView webView = findViewById(R.id.web_view); WebSettings webSettings = webView.getSettings(); // 设置UA String customUserAgent = "MyCustomUserAgent"; webSettings.setUserAgentString(customUserAgent); // 根据需要切换UA Button btnSwitchUA = findViewById(R.id.btn_switch_ua); btnSwitchUA.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String currentUA = webSettings.getUserAgentString(); if (currentUA.equals(customUserAgent)) { webSettings.setUserAgentString(null); } else { webSettings.setUserAgentString(customUserAgent); } // 刷新WebView webView.reload(); } }); ``` 以上代码中,我们首先获取到一个WebView实例,并通过调用`getSettings()`方法获取到WebView的WebSettings对象,从而对WebView进行一些配置。其中,我们通过`setUserAgentString()`方法设置了一个自定义的UA字符串,这个UA字符串可以是任何你想设置的值。 接着我们又添加了一个按钮,并为这个按钮设置了点击事件。当用户点击这个按钮时,我们会先获取当前WebView的User-Agent字符串,然后判断当前UA是否等于我们之前设置的自定义UA,如果是,则将WebView的User-Agent设置为null,表示使用默认的UA;否则,将User-Agent设置为之前设置的自定义UA,这样便完成了UA的切换。最后,我们调用Webview的`reload()`方法,刷新页面。 需要注意的是,WebView的UA只能设置一次,并且在设置之后,需要重新加载页面才能生效。同时,切换UA时也需要刷新页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值