Maven系列——構建我的Android項目

本博客為個人原創,轉載需在明顯位置注明出處

在正式開始本篇文章之前,你需要做一些準備工作,他們是:

  1. android-maven-plugin

  2. android-sdk-deployer

關于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,將打好的包上傳至遠程倉庫,并可以在另一個工程里面成功依賴。首先我們來看一下工程目錄:

Paste_Image.png

咦,為什么有兩個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

如果你的配置沒有問題,你會看到:

mvn clean
mvn package

查看一下module根目錄,多了一個target文件夾,里面裝著Maven構建好的文件,要啥有啥:

target

接著繼續敲命令:

~$mvn install

運行結果就不貼了哈,運行成功以后,咱們來看看打好的包有沒有裝進Maven本地倉庫:

local repository

特別注意我標記的三個紅框哈,從左到右他們分別是groupId,artifactId和version

最后上傳到遠程倉庫去,還記得第一篇文章的最后讓大家先注冊好Maven中央倉庫的賬號嘛,這時候就派上用場了

~$mvn deploy

上傳成功,我們另外新建一個AS工程,注意這里是新工程而不是新的module哈,然后在新工程gradle中compile 'com.will4it:bombframe:1.0.0-SNAPSHOT'來依賴看看:

gradle config

如圖,在依賴的時候你需要做兩項配置,一個是配置maven倉庫的地址,就是圖中repository中的url,為什么?因為gradle默認是從jcenter中尋找依賴包的,上面我們打的包是放在Maven中央倉庫或者公司私服倉庫的,所以你需要告訴gradle還需要訪問哪些倉庫地址,這樣gradle才能幫你找到;另一個就是compile 'groupId:artifactId:version'了,不解釋。來看看結果吧

gradle result

至此,Maven系列文章就結束了,希望我的分享能夠幫助到你,一定要動手自己操作。時間有限能力一般,文章中可能有些問題我沒說清楚或者理解錯的,歡迎大家踴躍拍磚!

注:可能你還會有疑問,我們的代碼是需要混淆的,Maven好像是支持javadoc的生成的?經過這四篇文章的學習練習,相信你應該有這個能力自己去摸索

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,765評論 25 708
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,829評論 18 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,923評論 6 342
  • 真宮寺是清睜開眼睛。 眼前是人類。 領頭的人挑起了他的下巴,摘掉口罩,眼神里有淋漓盡致的本性。是區別于好品質的更偉...
    二慝閱讀 6,425評論 2 6
  • 本來不想寫了,此刻吃完湯圓,家里燈火通明,每個人的眼睛都透著異樣興奮的目光。 我是累了,他們沒累。 突然想說說今天...
    瓶子時光閱讀 297評論 2 2