這個driver是UIAutomator1的driver,負責UIAutomator1的服務啓動、中止、命令接收和執行。javascript
appium-android-driver(NodeJS工程)java
自己appium-android-driver是一個nodejs工程,它還套着一個bootstrap的maven工程,這個maven工程就是用來打包UIAutomator1的,會再bootstrap/bin的目錄下構建生成一個叫AppiumBootstrap.jar的供外層的NodeJS工程使用。代碼在appium-android-driver/lib/bootstrap.js
的start函數中node
<!--more-->android
const rootDir = path.resolve(__dirname, '..', '..'); const startDetector = (s) => { return /Appium Socket Server Ready/.test(s); }; const bootstrapJar = path.resolve(rootDir, 'bootstrap', 'bin', 'AppiumBootstrap.jar'); await this.init(); await this.adb.forwardPort(this.systemPort, 4724); this.process = await this.uiAutomator.start( bootstrapJar, 'io.appium.android.bootstrap.Bootstrap', startDetector, '-e', 'pkg', appPackage, '-e', 'disableAndroidWatchers', disableAndroidWatchers, '-e', 'acceptSslCerts', acceptSslCerts);
bootstrap工程是一個maven工程,用idea直接open這個文件夾便可,找到pom.xml,右鍵Maven->Reimport,咱們會發現有兩個maven依賴沒法導入,報找不到對應的jar包:shell
<dependency> <groupId>android</groupId> <artifactId>android</artifactId> <version>4.4.2_r4</version> </dependency> <dependency> <groupId>android.test.uiautomator</groupId> <artifactId>uiautomator</artifactId> <version>4.4.2_r4</version> </dependency>
緣由是默認的倉庫是從https://repo.maven.appache.org/maven2中找的,而這個倉庫根本沒有這兩個庫。npm
後來我發現Boundless的倉庫http://repo.boundlessgeo.com/main/中是有的,在這個pom.xml中配置這個倉庫就能夠下載了。json
<project> ... <repositories> <repository> <id>Boundless</id> <url>http://repo.boundlessgeo.com/main/</url> </repository> </repositories> </project>
依賴庫搞定後,cmd切換到bootstrap文件夾目錄下,執行mvn clean package
構建maven工程,咱們會發現,並無在bin目錄下生成AndroidBootstrap.jar,此時要修改pom.xml中的maven-jar-plugin
:bootstrap
<plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <!--jar輸出目錄--> <outputDirectory>./bin</outputDirectory> <!--輸出的jar包名稱--> <finalName>AppiumBootstrap</finalName> </configuration> </plugin>
從新執行mvn clean package
,AppiumBootstrap.jar就完成了正常構建,也就是說UIAutomator1構建好了。併發
找到appium-android-driver/package.json,修改name,好比修改成appium-android-driver2
,而後順便修改下version,而後再appium-android-driver根目錄下執行app
npm install # 從新安裝依賴 npm publish # 發佈
npm publish
是發佈nodejs包的命令,須要你在npmjs.com)上註冊本身的帳號,發佈的時候須要驗證你的帳號。
跟自定義appium-android-driver同樣,咱們找到package.json,修改name和version,好比分別是appium2和1.12.1-20190401a,順便咱們修改一下lib/main.js中的一條語句,以驗證咱們的修改是否生效:
async function logStartupInfo (parser, args) { let welcome = `Welcome to Appium2 v${APPIUM_VER}, modified by chengming`; // 我修改了此處 let appiumRev = await getGitRev(); if (appiumRev) { welcome += ` (REV ${appiumRev})`; } logger.info(welcome); let showArgs = getNonDefaultArgs(parser, args); if (_.size(showArgs)) { logNonDefaultArgsWarning(showArgs); } let deprecatedArgs = getDeprecatedArgs(parser, args); if (_.size(deprecatedArgs)) { logDeprecationWarning(deprecatedArgs); } if (!_.isEmpty(args.defaultCapabilities)) { logDefaultCapabilitiesWarning(args.defaultCapabilities); } // TODO: bring back loglevel reporting below once logger is flushed out // logger.info('Console LogLevel: ' + logger.transports.console.level); // if (logger.transports.file) { // logger.info('File LogLevel: ' + logger.transports.file.level); // } }
還有要在package.json
中,找到dependencies,把咱們的appium的UIAutomator1的依賴改成"appium-android-driver2":"latest",使咱們自定義的appium可以使用咱們自定義的UIAutomator1 driver
一樣,從新構建和發佈:
npm install npm publish
在npmjs.com網站中,個人項目下就會看到appium2的工程:
npm i -g appium2
appium
這個要修改bootstrap的java代碼,在啓動server的時候加上你的日誌便可驗證,後續再補充吧。
官方readme.md沒有說怎麼打包這個jar包的事情,我按照如上述的打包方式生成的jar是不可用的,格式不正確。jar中的內容應該是一個classes.dex文件,而不是編譯好的classes。
咱們須要先把class文件打包成dex,而後再把dex打包成jar,shell代碼以下:
dx --dex --output=./classes.dex target/classes jar -cvf AppiumBootstrap.jar -C ./ ./classes.dex
你須要配置好android的環境變量,使你的dx可以全局調用。
既然打包方式知道了,而且appium是要求在appium-android-driver/bootstrap/bin下有個AppiumBootstrap.jar的,那麼咱們去掉此前給maven-jar-plugin設置的configuration,從新編寫一個shell腳本bootstrap.sh:
#!/bin/sh mvn clean package # 清理環境,編譯class文件 dx --dex --output=./target/classes.dex target/classes # 將class文件打包,生成dex文件 jar -cvf bin/AppiumBootstrap.jar -C ./ ./target/classes.dex # 將dex文件打包,生成jar
咱們找到bootstrap工程中的io.appium.android.bootstrap.Bootstrap.java
,在testRunServer方法的第一句,添加一段註釋:
public class Bootstrap extends UiAutomatorTestCase { public void testRunServer() { Logger.info("這是我自定義的Bootstrap,成功啦..."); Find.params = getParams(); boolean disableAndroidWatchers = Boolean.parseBoolean(getParams().getString("disableAndroidWatchers")); boolean acceptSSLCerts = Boolean.parseBoolean(getParams().getString("acceptSslCerts")); SocketServer server; try { server = new SocketServer(4724); server.listenForever(disableAndroidWatchers, acceptSSLCerts); } catch (final SocketServerException e) { Logger.error(e.getError()); System.exit(1); } } }
電腦插上手機,執行:
adb devices
輸出:
chengmingdeMacBook-Pro:bootstrap cmlanche$ adb devices List of devices attached cf02d869 device
確保你的手機是連上電腦的。
保存,執行bootstrap.sh,在bin目錄會打包好AppiumBootstrap.jar,咱們把它push到手機:
adb push ./bin/AppiumBootstrap.jar /data/local/tmp/AppiumBootstrap.jar
完成後,咱們啓動UIAutomator1的測試:
adb shell uiautomator runtest /data/local/tmp/AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap
自定義AppiumBootstrap至此流程已通,接下來就是自定義權限框處理,讓Appium自主識別權限框。
—— by cmlanche.com