第一种:自定义AppiumBootstrap.jar
Android上使用了instrumentation(uiautomator2)和uiautomator1两套技术,这是Uiautomator1的方式
下载源码:
https://github.com/appium-boneyard/appium-android-bootstrap
导入IDEA,见下图
导入android.jar和uiautomator.jar两个包,不知道在哪里可以用 Everything 搜索,一般只要装SDK环境了都可以找到,这里我用的是
导入之后应该就不会报错了,
在UiWatcher.java中增加
UiDevice.getInstance().registerWatcher("PopWindows", new UiWatcher() {
public boolean checkForCondition() {
System.out.println("UiWatcher:PopWindows");
UiObject uiObject = new UiObject((new UiSelector()).packageName("com.android.settings").textContains("保持连接"));
UiObject allowBtn = new UiObject((new UiSelector()).resourceId("android:id/button1").textContains("允许"));
if (uiObject.exists()) {
try {
uiObject.click();
return true;
} catch (UiObjectNotFoundException uiObjectNotFoundException) {
Log.e(UiWatchers.LOG_TAG, "dialog gone?", (Throwable)uiObjectNotFoundException);
}
}else if(allowBtn.exists()){
try {
allowBtn.click();
return true;
} catch (UiObjectNotFoundException uiObjectNotFoundException) {
Log.e(UiWatchers.LOG_TAG, "dialog gone?", (Throwable)uiObjectNotFoundException);
}
}
return false;
}
});
Log.i(LOG_TAG, "Registed GUI Exception watchers");
之后全部编译为.class文件,在/out目录可以看到编译后的文件,
1.然后不用管META-INF,只需要将com和io两个文件夹一起打包至classes.jar(原来直接用右键添加到压缩文件就行啊,我真服了找半天) 压缩到classes.jar文件
2.用dex2jar 下载地址: https://sourceforge.net/projects/dex2jar/
命令: d2j-jar2dex /your path/classes.jar -o classes.dex
3.将classes.dex和META-INF一并打包至AppiumBootstrap.jar,将得到的jar包放在Appium Server安装目录中替换
需注意,运行Appium server时需要在caps里加上 “automationName”: "UiAutomator1"属性
该方式缺陷是弹窗点掉之后,页面元素就获取不到了
第二种:编译appium-uiautomator2-server源码
即通过instrumentation的方式,Appium是通过安装appium-uiautomator2-server-debug-androidTest.apk和appium-uiautomator2-server-v4.27.0.apk与手机通信
Github地址:https://github.com/appium/appium-uiautomator2-server
这里我下载的是4.27.0,下载之后使用AndroidStudio编译,需注意这里需要使用jdk11,用jdk8是编译不过的
这里我尝试在AndroidServer.java里添加了监听器,但好像没什么卵用
public AndroidServer(int port) {
webServer = new HttpServer(port);
init();
addWatcher(); //添加监听
Logger.info("AndroidServer created on port " + port);
}
public void addWatcher() {
getUiDevice().registerWatcher("PopWindow", new UiWatcher() {
@Override
public boolean checkForCondition() {
/**meizu **/
//Logger.info("安装应用时,检查弹窗并点击允许");
System.out.println("UiWathcher:PopWindow");
if (getUiDevice().hasObject(By.pkg(Pattern.compile("android")).text(Pattern.compile("允许")))) {
Logger.info("find the button: By.pkg(Pattern.compile(\"android\")).text(Pattern.compile(\"允许\")), click it");
getUiDevice().findObject(By.pkg(Pattern.compile("android")).text(Pattern.compile("允许"))).click();
}
return false; // no trigger);
}
});
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);
}
编译命令:
** .\gradlew clean assembleServerDebug assembleServerDebugAndroidTest**
没有错误的情况下会在/app/build/outputs/apk目录下生成两个apk,同理将appium server中的apk替换掉再重启服务,需注意,运行Appium server时需要在caps里加上 “automationName”: "UiAutomator2"属性 ,但watcher似乎没有生效…有没有大佬可以告诉我怎么搞
第三种:最LOW的但同时最有效的
try:
driver.switch_to.alert.accept()
except:
pass
这纯属是没辙了,目前打算就这么干了…