本博客為個人原創,轉載需在明顯位置注明出處
在正式開始本篇文章之前,你需要做一些準備工作,他們是:
關于android-maven-plugin:我們知道Maven只是一座工廠,真正工作的是plugin,由于Android不同于Java,需要構建aar或者apk包,這就是android-maven-plugin存在的意義。雖說讓你準備,并不是說讓你預先安裝環境什么的,而是需要你先弄清楚android-maven-plugin是干嘛的,再讀一讀官方文檔中的使用引導,待真正使用的時候才不會感覺太陌生而措手不及
關于android-sdk-deployer:在編譯項目時需要在pom.xml中配置項目所有的依賴,例如junit、gson、fresco等等。對于一個Android項目,Android SDK的依賴是必須的。我們在Android Studio中編譯項目依賴的是我們本機中下載好的SDK,但是用Maven構建時,所有的dependency都會從本地倉庫中依賴,如果本地倉庫沒有再從遠程倉庫中下載,而這恰恰就是問題,因為Maven中央倉庫中Android SDK的最高版本僅為4.1.1(不太清楚Google為什么沒有繼續上傳新版本SDK),現在遠遠達不到我們編譯代碼的要求,所以我們就得自己想辦法。android-sdk-deployer可以幫助我們將你本機安裝的Android SDK整理打包,放入本地Maven倉庫,這樣我們就可以在項目中依賴任何版本的SDK了。
好了,有了上面兩項準備,我們就可以正式開始構建自己的Android項目,為此我創建了一個名為Bomb的工程(點我查看),其中有兩個module,一個是app,另一個是bombframe,我們的目標就是構建bombframe,將打好的包上傳至遠程倉庫,并可以在另一個工程里面成功依賴。首先我們來看一下工程目錄:
咦,為什么有兩個pom文件?還記得之前我說過,pom文件也是有繼承關系的,在實際項目中,我們一個工程下會有多個module,他們肯定需要公共的插件,公共的依賴,這就是為什么有兩個pom文件的原因。工程根目錄下的pom文件為父pom,其中定義的是公共的plugin和dependency,而bombframe中的pom為子pom,定義的則是其自身的一些特殊配置,下面我們先從父pom開始介紹,由于配置較多,我分段展示講解:
<groupId>com.will4it</groupId>
<artifactId>bomb-frame-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>bomb-frame-parent</name>
<modules>
<module>bombframe</module>
</modules>
父pom不真正提供構建,它有兩個作用,一是將一些公共的配置集中存放,二是mvn命令執行的入口,所以packaging不是具體的打包類型,而是pom,你只需記住所有的父pom文件的packaging都是pom就行。另外就是modules,大家應該可以看的明白,這里面定義的是所有的子項目,將需要構建的所有module子項目配置上即可。(這里配置的子項目名是AS工程的module名,跟子pom文件里面的name沒關系哈,至少一開始我是這么錯誤的認為的,結果走了彎路)
<properties>
<android.maven.plugin.version>4.4.3</android.maven.plugin.version>
<compiler.version>3.1</compiler.version>
<javadoc.version>2.9.1</javadoc.version>
<android.sdk.path>/Users/mowei/Documents/Software/adt-bundle-mac-x86_64-20140321/sdk
</android.sdk.path>
<android.sdk.version>21</android.sdk.version>
</properties>
properties我就不多說了,大家復制粘貼就行,將定義的值修改成適合你項目的就行
<dependencyManagement>
<dependencies>
<dependency>
<groupId>android</groupId>
<artifactId>android</artifactI
<version>5.1.1_r2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
這里要強調一下,作為父pom,在定義公共dependency的時候,最外層需要加上一層dependencyManagement,沒有為什么記住就行。另外這里只定義了一個dependency,就是我們的Android SDK,是通過上述android-sdk-deployer生成的。細心的童鞋應該可以發現groupId和version有點不太對勁,是的,我估計android-sdk-deployer的作者是為了跟Maven中央倉庫的SDK做個區分。
<build>
<plugins>
<plugin>
<groupId>com.simpligility.maven.plugins</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>${android.maven.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<failOnNonStandardStructure>false</failOnNonStandardStructure>
<sdk>
<path>${android.sdk.path}</path>
<platform>${android.sdk.version}</platform>
</sdk>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler.version}</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
接著就是構建這個工程需要的公共plugin,第一個就是讓大家準備的android-maven-plugin,需要解釋的是configuration標簽,這里面是針對plugin做一些配置的更改。failOnNonStandardStructure的意思是在發現工程結構有錯誤的情況下不終止不報錯,可以翻看一下Maven系列第一篇文章,一開始我就介紹了Maven構建對工程目錄的要求,里面有一個resource目錄,在我們Android Studio工程中默認是不存在的,但是Maven會嚴格檢查工程結構,一旦不是標準結構就會終止構建并且報錯,failOnNonStandardStructure就是為了跳過這一項。第二個是java compiler plugin,沒有什么難理解的東西,就是配置JDK的版本和編碼格式。
<distributionManagement>
<repository>
<id>releases</id>
<url>你的遠程release倉庫地址</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>你的遠程snapshot倉庫地址</url >
</snapshotRepository>
</distributionManagement>
最后一段配置就是你的遠程倉庫的地址,光看配置沒什么難理解的,之前給大家解釋過snapshot和release的區別,就連倉庫地址也是區分開的,這就是專業、標準。另外,上傳到遠程倉庫是需要用戶名和密碼的,這個就需要/.m2/settings.xml文件來管理了,在我看來這個問題比較簡單,咨詢一下度娘你可以搞的定,如果你搞不定,可以給我評論,最后我統計一下人數,如果人數比較多,我會再寫一篇文章專門講解settings文件的配置使用。
以上就是父pom文件的配置,雖然有點長,但是分析下來還是不難的,只要你夠耐心夠細心,這些都不是問題。下面我們繼續看子pom:
<groupId>com.will4it</groupId>
<artifactId>BombFrame</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>aar</packaging>
<name>BombFrame</name>
<parent>
<groupId>com.will4it</groupId>
<artifactId>bomb-frame-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
在子pom文件中,我們就可以定義packaging為對應的打包類型,這里我們需要構建的是aar包。另外,雖然pom也是繼承關系,但是這種繼承關系并不像Java代碼那么智能,需要手動制定自己的parent是誰,還需要制定父pom文件的路徑,這里大家注意一下即可
<properties>
<keystore>bomb_keystore.jks</keystore>
<key.store.password>bomb123456</key.store.password>
<key.alias>bomb</key.alias>
<key.alias.password>bomb123456</key.alias.password>
</properties>
依然只是properties的定義,這里基本上都是用于簽名的keystore信息,下面jarsigner plugin里面需要
<dependencies>
<dependency>
<groupId>android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
這里還需注意,雖然父pom文件中已經定義了Android SDK的依賴,但是子pom中還得重新指定一次,只是version不需要指定,對于dependency,父pom定義的作用主要是統一使用的version,所以子pom中還得再指定一次,如果version不指定,默認就是使用父pom中的版本,如果指定了就使用指定的版本。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>signing</id>
<goals>
<goal>sign</goal>
</goals>
<phase>package</phase>
<inherited>true</inherited>
<configuration>
<includes>
<include>target/*.aar</include>
</includes>
<keystore>${keystore}</keystore>
<storepass>${key.store.password}</storepass>
<keypass>${key.alias.password}</keypass>
<alias>${key.alias}</alias>
<arguments>
<argument>-sigalg</argument>
<argument>MD5withRSA</argument>
<argument>-digestalg</argument>
<argument>SHA1</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
對于plugin就不需要重復指定了,除非是該module獨有的plugin,就像這里的jarsigner plugin一樣,在打包成功之后,我們需要對aar包進行簽名,這里配置的都是一些簽名相關信息。
ok,到這里,我們的配置就結束了,在真正執行命令之前,再給大家詳細解釋一下以下幾個常用命令的含義:
mvn package:在需要打包的項目或者module的pom文件相同目錄下,創建一個target文件夾,然后執行編譯構建打包操作,最后將打好的包等所有相關文件都存入target文件夾中
mvn clean:參考package命令,clean的作用就是刪除整個target文件夾
mvn install:在package的基礎上,再將打好的包存入本地的Maven倉庫
mvn deploy:在install的基礎上,將打好的包和pom文件等上傳至遠程倉庫中
清楚這些命令的作用之后,我們就一起來試試看:
~$mvn clean
~$mvn package
如果你的配置沒有問題,你會看到:
查看一下module根目錄,多了一個target文件夾,里面裝著Maven構建好的文件,要啥有啥:
接著繼續敲命令:
~$mvn install
運行結果就不貼了哈,運行成功以后,咱們來看看打好的包有沒有裝進Maven本地倉庫:
特別注意我標記的三個紅框哈,從左到右他們分別是groupId,artifactId和version
最后上傳到遠程倉庫去,還記得第一篇文章的最后讓大家先注冊好Maven中央倉庫的賬號嘛,這時候就派上用場了
~$mvn deploy
上傳成功,我們另外新建一個AS工程,注意這里是新工程而不是新的module哈,然后在新工程gradle中compile 'com.will4it:bombframe:1.0.0-SNAPSHOT'來依賴看看:
如圖,在依賴的時候你需要做兩項配置,一個是配置maven倉庫的地址,就是圖中repository中的url,為什么?因為gradle默認是從jcenter中尋找依賴包的,上面我們打的包是放在Maven中央倉庫或者公司私服倉庫的,所以你需要告訴gradle還需要訪問哪些倉庫地址,這樣gradle才能幫你找到;另一個就是compile 'groupId:artifactId:version'了,不解釋。來看看結果吧
至此,Maven系列文章就結束了,希望我的分享能夠幫助到你,一定要動手自己操作。時間有限能力一般,文章中可能有些問題我沒說清楚或者理解錯的,歡迎大家踴躍拍磚!
注:可能你還會有疑問,我們的代碼是需要混淆的,Maven好像是支持javadoc的生成的?經過這四篇文章的學習練習,相信你應該有這個能力自己去摸索