UiAutomationConnection之Android4.3的新类

介绍Android 4.3中新增的UiAutomationConnection类,该类用于Instrumentation测试中控制特定操作权限,允许模拟用户动作及执行跨应用测试。文章详细阐述了其工作原理及远程调用机制。
Android 4.3上,Google的开发者新增了一个类UiAutomationConnection,它目前用在Instrumentation test中,控制某些操作的权限。
 
 
代码解释是这样说的:
 
UiAutomationConnection是一个远程对象,它从shell中传递给Instrumentation,用于控制某些特权操作,使得这些操作shell可以做,但Instrumentation不能做。这些特权操作需要实现UiAutomation,用来通过模拟用户动作和执行屏幕检测来实现跨应用的测试。
 
 
这里的shell实际上就是运行am.jar的进程,当用户通过shell命令运行一个测试,例如:
 
adb shell am instrument -e class com.android.browserpowertest.PowerMeasurement#myTest1 -w com.android.browserpowertest/com.android.browserpowertest.PowerTestRunner
 
这样就会在手机上启动一个shell进程,它将调用runInstrument来触发测试过程。
 
 
下面是4个时序图(中间用绿色横条分隔),分别描述的是:
 
1. 启动测试,shell创建UiAutomationConnection对象,并通过AMS传递给TestApp.
 
2. 测试完成后退出的过程。
 
3. TestApp调用connect.
 
4. TestApp调用disconnect.
 
 
从图中发现:UiAutomationConnection的对象是在shell进程中创建,调用它的成员函数,如connect或disconnect都是跨进程的远程调用(通过binder)。
用例 初始化失败 | 抖音调节音量-Super_Douyin_0002 | INFO: [UiAutomator2Server] Starting Server java.lang.IllegalStateException: UiAutomationService android.accessibilityservice.IAccessibilityServiceClient$Stub$Proxy@f2b79falrea dy registered! at android.os.Parcel.createExceptionOrNull(Parcel.java:2473) at android.os.Parcel.createException(Parcel.java:2449) at android.os.Parcel.readException(Parcel.java:2432) at android.os.Parcel.readException(Parcel.java:2374) at android.view.accessibility.IAccessibilityManager$Stub$Proxy.registerUiTestAutom ationService(IAccessibilityManager.java:830) at android.app.UiAutomationConnection.registerUiTestAutomationServiceLocked(UiAuto mationConnection.java:532) at android.app.UiAutomationConnection.connect(UiAutomationConnection.java:109) at android.app.UiAutomation.connectWithTimeout(UiAutomation.java:327) at java.lang.reflect.Method.invoke(Native Method) at mirror.RefMethod.call(RefMethod.java:63) at uiautomator.InstrumentShellWrapper.getUiAutomation(InstrumentShellWrapper.java: 101) at androidx.test.uiautomator.UiDevice$Api24Impl.getUiAutomationWithRetry(UiDevice. java:1545) at androidx.test.uiautomator.UiDevice.getUiAutomation(UiDevice.java:1468) at androidx.test.uiautomator.QueryController.<init>(QueryController.java:95) at androidx.test.uiautomator.UiDevice.<init>(UiDevice.java:115) at androidx.test.uiautomator.UiDevice.getInstance(UiDevice.java:296) at com.wetest.uia2.Main.runServer(Main.java:50) at com.wetest.uia2.Main.main(Main.java:30) at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:398) Caused by: android.os.RemoteException: Remote stack trace: at com.android.server.accessibility.UiAutomationManager.registerUiTestAutomationSe rviceLocked(UiAutomationManager.java:111) at com.android.server.accessibility.AccessibilityManagerService.registerUiTestAuto mationService(AccessibilityManagerService.java:1324) at android.view.accessibility.IAccessibilityManager$Stub.onTransact(IAccessibility Manager.java:404) at android.os.Binder.execTransactInternal(Binder.java:1211) at android.os.Binder.execTransact(Binder.java:1175) callee: null 1537/3726 java.lang.IllegalStateException: UiAutomation not connected, UiAutomation@d46de31 at android.app.UiAutomation.throwIfNotConnectedLocked(UiAutomation.java:1498) at android.app.UiAutomation.getServiceInfo(UiAutomation.java:614) at androidx.test.uiautomator.UiDevice.getUiAutomation(UiDevice.java:1482) at androidx.test.uiautomator.QueryController.<init>(QueryController.java:95) at androidx.test.uiautomator.UiDevice.<init>(UiDevice.java:115) at androidx.test.uiautomator.UiDevice.getInstance(UiDevice.java:296) at com.wetest.uia2.Main.runServer(Main.java:50) at com.wetest.uia2.Main.main(Main.java:30) at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:398)
最新发布
07-24
<think>好的,用户遇到了测试用例初始化失败的问题,错误信息主要涉及`UiAutomationService already registered`和`UiAutomation not connected`。我需要分析这些错误的原因,并给出解决方法。 首先,`UiAutomationService already registered`通常表示设备上已经有一个UiAutomation服务实例在运行,而测试尝试注册另一个实例,导致冲突。这可能是因为之前的测试没有正确清理资源,或者多个测试同时运行,占用了同一个服务。 接下来,`UiAutomation not connected`可能是因为UiAutomation服务未成功连接,可能是由于前一个错误导致服务注册失败,或者连接超时。 需要考虑的原因可能有: 1. 之前的测试会话未正确终止,残留的UiAutomation服务未释放。 2. 多个测试用例同时运行,导致多个UiAutomation实例冲突。 3. 设备或模拟器的系统版本与测试框架(如uiautomator2)不兼容。 4. 测试框架或驱动版本过旧,存在已知bug。 5. 设备资源不足(如内存),导致服务无法正常启动。 解决方法可能包括: - 确保每个测试用例结束后正确清理资源,关闭UIAutomator服务。 - 检查是否有残留的测试进程,通过adb命令终止相关进程。 - 调整测试配置,避免同时运行多个测试会话。 - 升级测试框架(如uiautomator2)和Appium到最版本。 - 重启设备或模拟器,释放被占用的服务。 - 检查设备日志,确认是否有其他冲突的服务或应用。 需要验证这些可能性,并给出具体的操作步骤,比如如何通过adb命令查看和终止残留进程,如何配置Appium以避免冲突,以及如何升级相关工具。 </think>你遇到的错误 `UiAutomationService already registered` 和 `UiAutomation not connected` 是 Android 自动化测试中典型的 **UIAutomation 服务冲突** 问题,核心原因是设备上已存在未释放的 UiAutomation 实例,导致测试会话无法注册或连接服务。以下是具体原因分析和解决方法: ### **一、核心原因分析** Android 的 `UiAutomation` 是系统级的自动化服务,同一时间仅允许一个实例运行(通过 AccessibilityManager 管理)。当以下情况发生时,会触发服务冲突: - **前测试会话未清理**:上一次测试结束后,未正确关闭 UiAutomation 服务(如 Appium 异常退出、`teardown` 未执行),导致服务残留。 - **多测试并发运行**:多个测试用例或工具(如 Appium、Espresso)同时尝试注册 UiAutomation 服务。 - **系统/框架兼容性问题**:设备系统版本(如 Android 12+)与测试框架(如 uiautomator2)不兼容,或框架存在已知 Bug。 ### **二、常见原因及解决方法** #### **1. 残留的 UiAutomation 服务未释放(最常见)** 前一次测试会话因异常终止(如 Appium 崩溃、测试超时),未正常关闭 UiAutomation 服务,导致会话无法注册。 **验证方法**: - 通过 `adb shell ps | grep uiautomator` 检查设备端是否存在残留的自动化进程(如 `io.appium.uiautomator2.server` 或 `com.android.uiautomator`)。 - 查看设备日志(`adb logcat | grep -i "UiAutomation"`),确认是否有服务未释放的记录。 **解决方法**: - **手动终止残留进程**: ```bash adb shell ps | grep uiautomator2.server # 找到进程 PID(如 1234) adb shell kill <PID> # 替换为实际 PID(如 adb shell kill 1234) ``` - **强制重启设备/模拟器**:通过 `adb reboot` 或手动重启设备,彻底释放系统资源。 #### **2.测试会话并发运行** 同时运行多个 Appium 测试会话(或混合使用其他自动化工具),导致多个 UiAutomation 实例竞争系统资源。 **验证方法**: - 检查 Appium 服务日志,确认是否有多个会话同时启动(如端口冲突、`systemPort` 重复)。 - 观察设备状态:测试过程中是否有其他自动化工具(如 Monkey、Espresso)运行。 **解决方法**: - **避免并发测试**:确保同一时间仅运行一个测试会话。 - **显式指定 `systemPort`**:在 `desired capabilities` 中为每个会话分配唯一端口(避免默认端口 8200 冲突): ```python desired_caps = { "systemPort": 8201, # 不同会话使用不同端口(如 8200、8201、8202) # 其他配置... } ``` #### **3. 测试框架或系统兼容性问题** - **uiautomator2 驱动版本过旧**:不兼容 Android 10+ 或高版本系统的服务管理机制。 - **设备系统版本限制**:部分 Android 版本(如 Android 13)对 UiAutomation 服务的注册有更严格的限制。 **解决方法**: - **升级 uiautomator2 驱动**:确保使用最版本(Appium 控制台执行 `appium driver install uiautomator2 --force`)。 - **降级设备系统版本**:若测试非必须高版本系统,可切换至 Android 9 或 10(兼容性更好)。 #### **4. 测试代码未正确清理资源** 测试的 `teardown` 方法未关闭 Appium 驱动或 UIA2 连接,导致服务未释放。 **验证方法**: 检查测试代码的 `teardown` 逻辑,确认是否调用了 `driver.quit()` 或 `ad.disconnect()`(uiautomator2 连接)。 **解决方法**: - 确保 `teardown` 中清理资源(示例代码): ```python def teardown(self): if self.driver: self.driver.quit() # 关闭 Appium 驱动(释放 UiAutomation 服务) if self.ad: self.ad.disconnect() # 断开 uiautomator2 连接 print("测试资源已清理") ``` #### **5. 设备性能不足或系统限制** 低性能设备(如老旧手机或模拟器)因内存/CPU 不足,导致 UiAutomation 服务启动超时或被系统杀死。 **解决方法**: - 关闭设备上无关应用,释放资源。 - 调整模拟器配置(如增加内存、CPU 核心数)。 ### **三、总结排查流程** 1. **终止残留进程**:通过 `adb kill` 清理设备端的 UIA2 服务进程。 2. **检查测试清理逻辑**:确保 `teardown` 正确释放驱动和连接。 3. **避免并发测试**:确保单一会话运行,或为不同会话分配唯一 `systemPort`。 4. **升级工具链**:更 uiautomator2 驱动和 Appium 到最版本。 5. **重启设备/模拟器**:彻底释放系统资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值