由於新項目需要在一台Android平台的設備中布署WEB服務器並提供內網接入者通過瀏覽器訪問WEB程序,遂考慮了Eclipse基金會的開源項目Jetty for Android,由於沒有接觸過所以已經做好心理准備會遇到一系列的問題,但猜到了開始卻沒猜到結局,解決問題的過程相當坎坷。這也是這篇隨筆出現的原因,一來為自己長記性,二來吧,對於Jetty for Android,網路上那些群魔亂舞的資料實在是太讓我無語了,毫無用處的博文實在是太多太多,有些在看的時候把人都看懵圈了,所以以本篇隨筆作為整理之用。
首先慣例環境說明:Windows XP sp3 (苦逼公司)、JDK1.7、Apache Maven 3.2.5、Git 2.6.4、eclipse luna 4.4.2。
關於環境的准備這里就不作說明了,相信作為軟件開發人員,不管老手菜鳥以上這些工具應該都玩得666的,怎么會沒有安裝不會配置呢。但還是要確定以下字段已聲明在系統變量,並將"import"文字后說明的目錄引入到Path屬性中:
JAVA_HOME -- java jdk root path --import:\bin;\jre\bin
MAVEN_HOME -- maven root path --import:\bin
ANDROID_HOME -- android sdk root path --import:\tools;\platform-tools
1,Download
參考Jetty for Android項目主頁利用Git將i-jetty代碼同步到本地。
$ git clone https://github.com/jetty-project/i-jetty.git
在查看Jetty for Android項目主頁時,注意到頁面中在說明Depedencies時並沒有說明Maven 的版本,但項目中Pom清單默認所依賴的類庫Jar包的版本若與當前系統使用的Maven 的版本互相不兼容,后面編譯項目時會出現一系列的問題,這點需要注意,關於項目中類庫的版本與Maven版本的支持關系在下面有說明。
該項目包含三個項目四個工程,有一個是web Example,i-jetty是jetty容器主體項目,console用於發布一個web-war到jetty容器中。我們只需要編譯打包i-jetty、console,然后將apk安裝到移動設備上。
2,Building i-jetty
下載完畢首先做的不應該是打開eclipse 來 Import Maven Project,不然等着你的將會是惡夢連篇,而首先要做的應該是修改項目Pom文件以適應本地環境,再使用Maven同步相應的依賴類庫項,確定本地環境能適應項目的編譯過程。
項目中默認在使用老得不能再老的Android API 4 平台,作者也是夠念舊的,我們暫時不改動它就用<platform>4</platform>,但請確認系統中已經下載了API 4 的SDK Platform,否則參考此親提供的下載Android API 4 platform。
注意解壓時不要直接解壓到ANDROID_HOME中,參考SDK的目錄結構,應在platforms,samples,system-images目錄中建立android-4放置相應文件,tools目錄內文件請對位入座。
此時我們還需要根據Maven 版本來修改項目中的Pom文件,例如我的為Apache Maven 3.2.5:i-jetty\i-jetty\i-jetty-ui\pom.xml
<plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId><!-- 改這里 --> <version>3.8.2</version><!-- 再改這里 --> <extensions>true</extensions> <configuration> <sdk> <platform>4</platform> </sdk> <deleteConflictingFiles>true</deleteConflictingFiles> <extractDuplicates>true</extractDuplicates> <undeployBeforeDeploy>true</undeployBeforeDeploy> </configuration> <executions> <execution> ... </execution> </executions> </plugin> <profiles> <profile> <id>sign</id> <build> <plugins> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId><!-- 還有改這里 --> <configuration> <sign> <debug>false</debug> </sign> </configuration> </plugin> </plugins> </build> </profile> </profiles>
* 注:maven-android-plugin在3.0.0版本開始已經更名為android-maven-plugin,而項目中還在使用maven-android-plugin : 2.9.0-beta-5,作者年齡暴露無遺。
若是其它Maven 版本具體請參考以下的版本支持修改范圍:
Maven 3.0.3 -- android-maven-plugin : 3.0.0
Maven 3.0.5 -- android-maven-plugin : 3.3.0~3.5.3
Maven 3.1.1 -- android-maven-plugin : 3.8.0~3.8.1
修改完畢,命令行定位到i-jetty\i-jetty目錄開始編譯apk:
mvn clean install
此時Maven會根據Pom清單同步依賴項到Maven的本地repository中,到這里你就開始祈禱吧... --(此處根據網速快進若時間)-- 如果一切正確無誤將會出現以下的編譯結果:
3,Using i-jetty
檢查i-jetty-ui\target\發現已經編譯成功的APK -- i-jetty-3.2-SNAPSHOT.apk ,將其安裝到設備中:
adb install -s "C:\Documents and Settings\Administrator\i-jetty\i-jetty\i-jetty-ui\target\i-jetty-3.2-SNAPSHOT.apk"
4,Building console
繼續編譯WEB項目,同樣是修改Pom清單適應本地編譯環境:i-jetty\console\webapp\pom.xml -- 從第70行開始
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2</version> <executions> <!-- Convert the compiled classes into a clases.dex. --> <execution> <id>generate-dex</id> <phase>process-classes</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <arguments> <argument>-jar</argument> <!-- 改為從android-api-4 解壓出來的dx.jar的正確路徑,用來將clss文件打包成dex文件 --> <argument>${env.ANDROID_HOME}/tools/lib/dx.jar</argument> <!--<argument>-JXmx1024M</argument>--> <argument>--dex</argument> <argument>--verbose</argument> <argument>--core-library</argument> <argument>--output=${project.build.directory}/classes.dex</argument> <argument>--positions=lines</argument> <argument>${project.build.directory}/classes/</argument> <argument>${project.build.directory}/generated-classes/</argument> </arguments> </configuration> </execution> </executions> </plugin>
修改完畢,命令行定位到i-jetty\console\webapp目錄開始編譯war:
mvn clean install
又是一陣焦急的等待...
5,Using console
這個WEB是提供給i-jetty-console-installer作為要發布的程序,其實可以手工直接將war解壓出來的console拷貝到/sdcard/jetty/webapps/下,這里演示過程需要所以將其copy到i-jetty-console-installer的res/raw/下,並將原來的空的console.war替換掉:
del "C:\Documents and Settings\Administrator\i-jetty\console\apk\res\raw\*.*"
copy "C:\Documents and Settings\Administrator\i-jetty\console\webapp\target\console-3.2-SNAPSHOT.war" "C:\Documents and Settings\Administrator\i-jetty\console\apk\res\raw"
rename "C:\Documents and Settings\Administrator\i-jetty\console\apk\res\raw\console-3.2-SNAPSHOT.war" console.war
6,Building i-jetty-console-installer
顧名思義作用就是將console.war解壓發布到i-jetty的工作目錄webapps/下,當然先要修改Pom清單:i-jetty\console\apk\pom.xml -- 從第69行開始
<plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId><!-- 改這里 --> <version>3.8.2</version><!-- 還有改這里 --> <extensions>true</extensions> <configuration> <sdk> <platform>4</platform> </sdk> <deleteConflictingFiles>true</deleteConflictingFiles> <extractDuplicates>true</extractDuplicates> <undeployBeforeDeploy>true</undeployBeforeDeploy> <resourceOverlayDirectories> <resourceOverlayDirectory>${project.build.directory}/res-overlay</resourceOverlayDirectory> </resourceOverlayDirectories> </configuration> <executions> <execution> <id>alignApk</id> <phase>package</phase> <goals> <goal>zipalign</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>sign</id> <build> <plugins> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId><!-- 最后改這里 --> <configuration> <sign> <debug>false</debug> </sign> </configuration> </plugin> </plugins> </build> </profile> </profiles>
翹起二郞腿命令行定位到i-jetty\console\apk目錄開始編譯apk,結果拋出了異常,好不容易硬起來一下子就又軟了:
從截圖可以看出Maven生命周期在執行 -- maven-dependency-plugin:2.0:copy-dependencies (copy-war) @ i-jetty-console-installer --的時候拋出了一個Warning Error injecting: org.eclipse.aether,connector.wagon.WagonRepositoryConnectorFactory ... ...
查看執行maven-dependency-plugin部分的goals,發現又是版本問題,其它maven-dependency-plugin都是用2.3版本的,唯獨i-jetty\console\apk\pom.xml這個在用2.0版本,將其修改為2.3版本:i-jetty\console\apk\pom.xml -- 從第46行開始
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.3</version><!-- 改這里 --> <executions> <execution> <id>copy-war</id> <phase>generate-sources</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/res-overlay/raw</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> <excludeTransitive>true</excludeTransitive> <stripVersion>true</stripVersion> <includeArtifactIds>console</includeArtifactIds> </configuration> </execution> </executions> </plugin>
修改完畢再編譯該Pom,結果 BUILD SUCCESS !!! 哈哈哈,二郞腿翹起來,並將其安裝到設備中。
7,Using i-jetty-console-installer
adb install -s "C:\Documents and Settings\Administrator\i-jetty\console\apk\target\i-jetty-console-installer-3.2-SNAPSHOT.apk"
從設備中運行I-Jetty-Console,點擊Install按鈕。提示 success ,此時/sdcard/jetty/webapps/下多了一項console的WEB目錄說明發布完成。
8,Browser console
查看設備WiFi Connector Information並從瀏覽器中訪問
adb shell shell@android:/ $ netcfg
這個是Jetty for Android提供的一個示例項目,可以通過參考其中源碼來了解如何從WEB中訪問設備內部的數據。本隨筆暫時到此結束,此處應有掌聲。