之前通过代码在 uiautomator2 server 的源码中添加了弹窗监听器,并通过 Timer 每隔 1 秒执行一次,
导致在部分手机(例如华为荣耀 8,小米 5S)中起 uiautomator2 server 后,获取 get 请求响应超时。
public void errorHandle() {
getUiDevice().registerWatcher("installAPP1", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 安装应用时,检查弹窗并点击允许 **/
if (getUiDevice().hasObject(By.pkg(Pattern.compile(".*android.*")).text(Pattern.compile(".*允许")))) {
Logger.info("installAPP1 window pop up");
getUiDevice().findObject(By.pkg(Pattern.compile(".*android.*")).text(Pattern.compile(".*允许"))).click();
return true;
}
if (getUiDevice().hasObject(By.pkg(Pattern.compile(".*systemmanager")).text(Pattern.compile(".*允许")))) {
Logger.info("installAPP1 window pop up");
getUiDevice().findObject(By.pkg(Pattern.compile(".*systemmanager")).text(Pattern.compile(".*允许"))).click();
return true;
}
return false;
}
});
getUiDevice().registerWatcher("installAPP2", new UiWatcher() {
@Override
public boolean checkForCondition() {
if (getUiDevice().hasObject(By.res(Pattern.compile(".*packageinstaller.*")).text(Pattern.compile(".*安装")))) {
Logger.info("installAPP2 window pop up");
getUiDevice().findObject(By.res(Pattern.compile(".*packageinstaller.*")).text(Pattern.compile(".*安装"))).click();
return true;
}
/** 安装应用时,点击安装按钮,其Id包含id和button **/
if (getUiDevice().hasObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*安装"))) && !getUiDevice().hasObject(By.res(Pattern.compile(".*packageinstaller.*")).text(Pattern.compile(".*商店")))) {
Logger.info("installAPP2 window pop up");
getUiDevice().findObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*安装"))).click();
return true;
}
return false;
}
});
getUiDevice().registerWatcher("okButton", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 适用于HTC手机,安装应用时,点击确定按钮 */
if (getUiDevice().hasObject(By.text(Pattern.compile(".*应用程序权限"))) && getUiDevice().hasObject(By.text(Pattern.compile(".*确定")))) {
Logger.info("okButton window pop up");
if(getUiDevice().hasObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*确定")))) {
getUiDevice().findObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*确定"))).click();
return true;
}else if(getUiDevice().hasObject(By.text(Pattern.compile(".*确定")))){
getUiDevice().findObject(By.text(Pattern.compile(".*确定"))).click();
return true;
}
}
/** 点击确认按钮,其Id包含 id和button */
if (getUiDevice().hasObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*确认")))) {
Logger.info("okButton window pop up");
getUiDevice().findObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*确认"))).click();
return true;
}
/** 点击确定按钮,其Id包含 id和button */
if (getUiDevice().hasObject(By.pkg(Pattern.compile(".*installer.*")).text(Pattern.compile(".*确定")))) {
Logger.info("okButton window pop up");
getUiDevice().findObject(By.pkg(Pattern.compile(".*installer.*")).text(Pattern.compile(".*确定"))).click();
return true;
}
return false;
}
});
getUiDevice().registerWatcher("pressContinue", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 点击Continue按钮*/
if (getUiDevice().hasObject(By.clazz("android.widget.Button").pkg("com.android.browser").text("Continue"))) {
Logger.info("Continue window pop up");
getUiDevice().findObject(By.clazz("android.widget.Button").pkg("com.android.browser").text("Continue")).click();
return true;
}
return false;
}
});
getUiDevice().registerWatcher("goodButton", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 点击“好”按钮*/
if (getUiDevice().hasObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*好")))) {
Logger.info("goodButton window pop up");
getUiDevice().findObject(By.res(Pattern.compile(".*id/.*button.*")).text(Pattern.compile(".*好"))).click();
return true;
}
return false;
}
});
getUiDevice().registerWatcher("ANR", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 手机ANR时,点击OK button*/
if (getUiDevice().hasObject(By.clazz("com.android.server.am.AppNotRespondingDialog"))) {
Logger.info("ANR window pop up");
if(getUiDevice().hasObject(By.text("OK"))){
getUiDevice().findObject(By.text("OK")).click();
}
return true;
}
return false;
}
});
getUiDevice().registerWatcher("ANR2", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 手机ANR时,点击OK button*/
if (getUiDevice().hasObject(By.pkg("android").text(Pattern.compile(".*isn't responding.*")))) {
Logger.info("ANR2 window pop up");
if(getUiDevice().hasObject(By.text("OK"))){
getUiDevice().findObject(By.text("OK")).click();
}
return true;
}
return false;
}
});
getUiDevice().registerWatcher("CRASH", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 手机CRASH时,点击OK button*/
if (getUiDevice().hasObject(By.clazz("com.android.server.am.AppErrorDialog"))){
Logger.info("CRASH window pop up");
if(getUiDevice().hasObject(By.text("OK"))){
getUiDevice().findObject(By.text("OK")).click();
}
return true;
}
return false;
}
});
getUiDevice().registerWatcher("CRASH2", new UiWatcher() {
@Override
public boolean checkForCondition() {
/** 手机CRASH时,点击OK button*/
if (getUiDevice().hasObject(By.pkg("android").text(Pattern.compile(".*has stopped.*")))){
Logger.info("CRASH2 window pop up");
if(getUiDevice().hasObject(By.text("OK"))){
getUiDevice().findObject(By.text("OK")).click();
}
return true;
}
return false;
}
});
// new Thread(new Runnable() {
//
// @Override
// public void run() {
// while(true) {
// getUiDevice().runWatchers();
// getUiDevice().waitForIdle(2000);//避免第一次runWatchers还没有完成,立即运行了第二次
// }
// }
// }).start();
// TimerTask updateWatchers = new TimerTask() {
// @Override
// public void run() {
// try {
// getUiDevice().runWatchers();
// } catch (final Exception e) {
// }
// }
// };
// Timer timer = new Timer("WatchTimer");
// timer.scheduleAtFixedRate(updateWatchers, 100, 2000);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
getUiDevice().runWatchers();
try {
getUiDevice().dumpWindowHierarchy(new File("/mnt/sdcard/test.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0, 2, TimeUnit.SECONDS);
}
结果是在 get 请求阶段长时间无响应,进而安装应用失败
[UiAutomator2] Starting uiautomator2 server v0.1.0 with cmd: am,instrument,-w,io
.appium.uiautomator2.server.test/android.support.test.runner.AndroidJUnitRunner
[UiAutomator2] running command...
adb -s 4449d8a9 shell am instrument -w io.appium.uiautomator2.server.test/andro
id.support.test.runner.AndroidJUnitRunner...
[UiAutomator2] Waiting for UiAutomator2 to be online...
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/h
ub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/h
ub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/h
ub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/h
ub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/h
ub/status] with no body
[debug] [JSONWP Proxy] Proxying [GET /status] to [GET http://localhost:8200/wd/h
ub/status] with no body
……
修改监听器的间隔时间,降为 2000,即 2 秒执行一次
TimerTask updateWatchers = new TimerTask() {
@Override
public void run() {
try {
getUiDevice().runWatchers();
} catch (final Exception e) {
}
}
};
Timer timer = new Timer("WatchTimer");
timer.scheduleAtFixedRate(updateWatchers, 100, 2000);
可能是因为手机中的相关进程是单例的,频繁的处理弹窗导致来不及响应用户的请求