【前言】
在使用Appium的時候,你可能會遇見各種各樣問題,如果不能很快在網上搜索解決,請耐心查看和分析Appium的輸出日志,因為不同的環境以及不同的目的都會有千奇百怪的問題,也許你遇見的問題網上就沒有人碰見過。
【背景以及環境】
我的開發環境是windows10 + Appium1.4.16.1 + IDEA + 真機測試。
當前,我配置好了desiredCapabilities,代碼如下:
1 // desiredCapabilities 2 capabilities = new DesiredCapabilities(); 3 capabilities.setCapability("automationName","Appium"); 4 capabilities.setCapability("platformName","Android"); 5 capabilities.setCapability("platformVersion","5.1"); 6 capabilities.setCapability("deviceName", DEVICE_UDID); 7 capabilities.setCapability("udid", DEVICE_UDID); 8 capabilities.setCapability("noSign", "true");
9 //getClassesDir()私有函數,得到當前項目編譯后的根目錄 10 capabilities.setCapability("app", getClassesDir()+"\\"+APP_PATH); 11 12 //使用aapt2來獲取安裝的apk的包名 13 //由於會打包,所以我先把這些工具拷貝到宿主操作系統的某處 14 Runtime runtime = Runtime.getRuntime();
15 //copyDirectoryFromJarToDisk(directoryPath)私有函數,將項目中的文件夾拷貝到磁盤上去 16 String toolPath = copyDirectoryFromJarToDisk("tool"); 17 String apkPath = copyDirectoryFromJarToDisk("apk"); 18 String command = toolPath+"/aapt2.exe d badging " 19 +apkPath+"/"+APP_PATH.split("/")[1];
//下面這段將aapt2 dump badging *.apk得到的apk信息導出到磁盤上的apkinfo.txt中去 20 if(System.getProperty("os.name").toLowerCase().startsWith("win")){ 21 command += " > "+toolPath+"/apkinfo.txt"; 22 } else { 23 command += " | "+toolPath+"/apkinfo.txt"; 24 } 25 runtime.exec(command);
// getApkInfo(infoName, apkInfoTxtPath)私有函數從apkinfo.txt文件中獲取相應字段 26 capabilities.setCapability("appPackage",getApkInfo("package",toolPath)); 27 capabilities.setCapability("appActivity",getApkInfo("launchable-activity",toolPath));
簡單說上面的主要工作是配置DesiredCapabilities,其中為了了解安裝的apk的包名和啟動Activity,我使用了aapt2工具,將結果導入到磁盤的某個txt文件中去。然后包名的信息就從這個文件中讀。
【問題以及解決對策,解決對策在第5點】
運行,報錯,控制台第一行出現
Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: Unable to create a new remote session. Please check the server log for more details. Original error: A new session could not be created. (Original error: UiAutomator quit before it successfully launched) (WARNING: The server did not provide any stacktrace information)
上面的內容說的就是UiAutomator(sdk提供的一個工具)沒有正常啟動。后來經過搜索,發現問題千奇百怪的,解決方案也五花八門,但是都不管用。於是就自行分析查看日志。過程如下:
1、查看appium日志,發現最早出現問題的是
是說要從Bilibili.apk讀取strings.json,但是string.json路徑里面有null值,因此不成功。不過影響不大,程序可以繼續執行。
2、繼續往下看
這里應該是執行卸載命令了,不過命令 adb -s $ANDROID_SERIAL uninstall PACKAGE 是可以執行的,但是上面提示uninstall還需要一個參數。接着往下看
3、
這里應該是問題關鍵了,Appium在之前拷貝它的AppiumBootstrap.jar到Android機器的/data/local/tmp下,然后這里的第一句使用了 adb shell uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap -e pkg PACKAGE 的語句來執行拷貝進去的AppiumBoostrap.jar,我在cmd中執行該句,當我省略 PACKAGE 時,得到了和上面一樣的錯誤。
4、
由此,我得知我傳進去的包名是有問題的,再看上面的打印出來的包名,發現格式不對。然后我使用vscode查看打印出的apkinfo.txt文檔,發現其編碼為UTF-16 LE。但是我的執行環境是utf-8,所以得到的包名在utf-8下看起來是這樣的:
可見,每個可見字符之間隔了一個 \u0000 ,由此解決方法也顯而易見了。
5、編碼格式的解決方法是,對從aapt2打印的結果文字,在讀取或者使用的時候進行轉碼,將 utf-16 LE 轉為 utf-8 。最簡單的方式就是除去多余的 \u0000 字符。比如對從文件中讀到的字符加上
StringReadFromAAPT = StringReadFromAAPT.replace("\u0000","");
【后記】
不管怎么說,遇到難題搜索無果時,耐心分析日志才能真正節約時間。