2015-03-19 5 views
2

Я перехожу от uiautomator к uiautomator 2.0. У меня возникают проблемы со старым UiWatcher.StaleObjectException с UiAutomator 2.0

Я использую эту функцию для установки уровня заряда батареи и проверки правильности печати приложения. Вот код.

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% (появляется диалоговое окно «Батарея разряжена»), StaleObjectException поднимается на линии Boolean b = batteryLevel.wait(Until.textEquals(newL + " %"), 10000);

Вот исключение

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()); 
... 

Но это абсолютно не красиво. Кто-нибудь

  • столкнулся с той же проблемой?
  • есть хорошее рабочее решение?

Благодаря

ответ

2

Эта проблема должна быть решена в UiAutomator 2.1.0. Наблюдатели запускались только при первоначальном вызове UiDevice.findObject(..) и не препятствовали StaleObjectExceptions.

В последней версии наблюдатели также будут запущены в случаях, когда вы получите исключение StaleObjectException. Если вы возьмете последний репозиторий поддержки Android (версия 13) и обновите файл сборки, зависящий от uiautomator-v18: 2.1+, проблема исчезнет.

+0

Спасибо! Он работает с uiautomator-v18: 2.1.1 – ThomasThiebaud

Смежные вопросы