使用UiAutomator 2.0的StaleObjectException

时间:2015-03-19 16:05:36

标签: android uiautomator android-uiautomator

我正在从uiautomator转到uiautomator 2.0。我和一个老的UiWatcher有一些麻烦。

我正在使用此功能设置电池电量并检查应用程序是否打印了正确的级别。这是代码。

private void setLevel(int oldL, int newL) throws UiObjectNotFoundException {
    UiWatcher okBatteryDialogWatcher = new UiWatcher() {
        @Override
        public boolean checkForCondition() {
            UiObject okCancelDialog = new UiObject(new UiSelector().textContains("Connect charger"));
            if(okCancelDialog != null){
                UiObject okButton = new UiObject(new UiSelector().className(Button.class.getName()).text("OK"));
                okButton.click();
                return device.waitForWindowUpdate("",10000);
            }
            return false;
        }
    };

    getUiDevice().registerWatcher("Battery dialog watcher", okBatteryDialogWatcher);
    getUiDevice().runWatchers();

    UiObject batteryLevel = new UiObject(new UiSelector().text(oldL + " %"));
    assertTrue("Battery level not found", batteryLevel.exists());

    BatteryDelegate.getInstance().setBatteryLevel(newL);

    batteryLevel = new UiObject(new UiSelector().text(newL + " %"));
    assertTrue("Battery level not found", batteryLevel.exists());
}

此代码工作正常。现在我想更改它以使用uiautomator 2.0提供的新功能。

private void setLevel(int oldL, int newL) {
    UiWatcher okBatteryDialogWatcher = new UiWatcher() {
            @Override
            public boolean checkForCondition() {
                UiObject2 okCancelDialog = device.findObject(By.textContains("Connect charger"));
                if(okCancelDialog != null){
                    UiObject2 okButton = device.findObject(By.clazz(Button.class.getName()).text("OK"));
                    okButton.click();
                    return device.waitForWindowUpdate("",10000);
                }
                return false;
            }
        };

    device.registerWatcher("Battery dialog watcher", okBatteryDialogWatcher);
    device.runWatchers();

    UiObject2 batteryLevel = device.findObject(By.text(oldL + " %"));
    assertTrue("Battery level not found", batteryLevel != null);

    BatteryDelegate.getInstance().setBatteryLevel(newL);

    Boolean b = batteryLevel.wait(Until.textEquals(newL + " %"), 10000);
    assertTrue("Battery level not found", b != null && b.booleanValue());
}

当我使用此代码将电池电量设置为5%时(出现“电池电量不足”对话框),会在Boolean b = batteryLevel.wait(Until.textEquals(newL + " %"), 10000);

上引发StaleObjectException

这是例外

android.support.test.uiautomator.StaleObjectException
at android.support.test.uiautomator.UiObject2.getAccessibilityNodeInfo(UiObject2.java:622)
at android.support.test.uiautomator.UiObject2.getText(UiObject2.java:287)
at android.support.test.uiautomator.Until$15.apply(Until.java:277)
at android.support.test.uiautomator.Until$15.apply(Until.java:274)
at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:49)
at android.support.test.uiautomator.WaitMixin.wait(WaitMixin.java:34)
at android.support.test.uiautomator.UiObject2.wait(UiObject2.java:144)
at com.mycompany.myproject.demo.sensor.BatteryTestCase.setLevel(BatteryTestCase.java:89)
at com.mycompany.myproject.demo.sensor.BatteryTestCase.testUS2(BatteryTestCase.java:44)
...

据我所知,执行是由于对话,但我的观察者变得毫无用处。我可以通过像

这样的技巧来处理这个异常
....
Boolean b = null;
try {
    b = batteryLevel.wait(Until.textEquals(newL + " %"), 10000);
} catch (StaleObjectException e) {
    UiObject2 okCancelDialog = device.findObject(By.textContains("Connect charger"));
    if(okCancelDialog != null){
        UiObject2 okButton = device.findObject(By.clazz(Button.class.getName()).text("OK"));
        okButton.click();
        device.waitForWindowUpdate("",10000);
        b = batteryLevel.wait(Until.textEquals(newL + " %"), 10000);
    }
}
assertTrue("Battery level not found", b != null && b.booleanValue());
...

但这绝对不美观。有人

  • 遇到同样的问题?
  • 有一个很好的工作解决方案吗?

由于

1 个答案:

答案 0 :(得分:2)

此问题应在UiAutomator 2.1.0中修复。监视器仅在初始调用UiDevice.findObject(..)时被触发,并且不会阻止StaleObjectExceptions。

在最新版本中,如果您收到StaleObjectException,也会触发观察者。如果您获取最新的Android支持存储库(修订版13)并更新您的构建文件以依赖于uiautomator-v18:2.1+,问题就会消失。