版本的統(tǒng)一管理
當(dāng)我們的工程中有許多module的時候,分開管理編譯版本,minsdk將會是一件很麻煩的事,因為一個library的改動,可能會影響到其他module。這時我們就需要對所有的版本進(jìn)行統(tǒng)一的管理,管理的方式有兩種:
rootProject
我們可以把一些需要用的字段都放在project的build.gradle(注意是project的不是module的)中:

這樣,在module的build.gradle中可以進(jìn)行讀?。?/span>

gradle.properties
找到工程目錄下的gradle.properties文件,如果沒有也可以自己創(chuàng)建:

然后在各個module的build.gradle中可以引用:

需要注意的是在gradle.properties中聲明的格式都是string類型,如果如要轉(zhuǎn)化成int類型,可以用as int 進(jìn)行強(qiáng)制轉(zhuǎn)化。
程序中對buildTypes的區(qū)分
buildTypes是對不同build類型的處理
當(dāng)你點(diǎn)擊運(yùn)行按鈕的時候會根據(jù)build Variant進(jìn)行對應(yīng)的方式編譯。
build Variant可以在這里進(jìn)行選擇:

Paste_Image.png
library的buildTypes
默認(rèn)情況下被依賴工程會使用release模式,與上層依賴的app工程選擇的模式無關(guān)
需要在build.gradle中進(jìn)行設(shè)置:

新增buildTypes
你可以在buildTypes,根據(jù)需要新增一個類型,如下代碼所示:

不同模式字符不同
根據(jù)上面的代碼,在不同的buildTypes中,TEXT這個變量是不一樣的,而且根據(jù)代碼可以看出,這個變量是一個String類型,那么我們在程序文件中可以這樣通過BuildConfig引用:
t2.setText(BuildConfig.TEXT);
Variant
gradle插件允許最終生成的包以多個維度進(jìn)行組合
例如我們可以設(shè)定一下幾個維度:

每個維度中可以設(shè)置這個版本的最小sdk限制,以及targetsdkversion
假設(shè)我們設(shè)置的維度有red blue yellow但是結(jié)合之前講過的buildType(假設(shè)只有debug和release)
那么將會出現(xiàn)以下構(gòu)建:
blueDebug和blueRelease
yellowDebug和yellowRelease
redDebug和redRelease
Gradle會為每一個Variant創(chuàng)建一個任務(wù)
對應(yīng)如下:
gradle assembleBlue 會生成debug和release兩個版本
gradle assembleDebug 會生成blue yellow red三個版本
gradle assembleBlueDebug 會生成bluedebug一個版本
這里還有一個用處需要提一下:
Gradle在打包android應(yīng)用之前會將所有的代碼,資源文件,包括manifest進(jìn)行結(jié)合,當(dāng)然library也會提供額外的資源,這些也會進(jìn)行合并。
字符串讀取
如果我們在創(chuàng)建一些設(shè)置時,需要動態(tài)的去更改內(nèi)容,可以設(shè)置一個變量,然后從本地文件或者打包的命令行讀取,我們這里就拿上面提到過的BuildConfig做例子,希望程序中引用的字符串是從本地讀取的或從命令行讀取的
從本地文件中讀取
首先需要在最開始的地方設(shè)置一個變量aaa:

Paste_Image.png
然后在buildTypes的debug模式中修改對應(yīng)的代碼:

然后在工程目錄下創(chuàng)建一個本地文件test.properties,并添加內(nèi)容:

Paste_Image.png
然后回到你剛才定義字符串的build.gradle中,添加:

即可讀取到你本地文件的字符串
從命令行讀取
如果是從命令行讀入就更加簡單,只需要將上面讀取文件的代碼改為:
aaa = new String(System.console().readLine("請輸入字符串:"))
編譯命令
首先想看一個工程包含了多少task,需要切到這個工程目錄下:
gradle tasks
會列出所有的tasks:

Paste_Image.png
當(dāng)然篇幅有限,這里不貼出所有的任務(wù)了,我們只需要知道編譯命令即可,如圖可以看到,如果想編譯debug版本,使用:
assembleDebug
其它同理即可。
如果使用build則回編譯出所有的版本
沖突問題

Paste_Image.png
在執(zhí)行打包的時候很有可能會出現(xiàn)如上問題,這是由于依賴的jar沖突問題,我們可以分析一下工程結(jié)構(gòu)。
我現(xiàn)在的結(jié)構(gòu)是:

Paste_Image.png
現(xiàn)在調(diào)整一下結(jié)構(gòu):

Paste_Image.png
把jar以module的形式提供就不會出現(xiàn)沖突。
編譯流程


Paste_Image.png
Task任務(wù)
執(zhí)行順序
例如我們新建一個任務(wù):

他的執(zhí)行如下:

Paste_Image.png
它并不是在執(zhí)行任務(wù)的時候執(zhí)行的,而是在執(zhí)行任務(wù)之前就打印了。
這是由于gradle構(gòu)建有三個階段:
初始化階段,配置階段,執(zhí)行階段。
上面的例子實(shí)際是打印在了配置階段,換句話說,你不執(zhí)行這個任務(wù),執(zhí)行這個工程別的任務(wù)也會打印。
例如我再寫一個任務(wù):

這次執(zhí)行這個任務(wù):

Paste_Image.png
你會發(fā)現(xiàn)也打印aaaa這說明這不是在真正的執(zhí)行階段執(zhí)行的,為了保證任務(wù)的可控性,可以像上面umengtestaa那樣寫加一個<<符號
這樣就可以保證了任務(wù)的可控性:

Paste_Image.png
或者使用:

打包任務(wù)
有了上面的基礎(chǔ),下面就可以說一下打包的任務(wù)了,根據(jù)我們之前的工程,我們有一個app的module和四個library module,我需要打印出一個apk和四個jar,明確了任務(wù),現(xiàn)在可以開始實(shí)施了。
打開工程的build.gradle

這時,我們再去找一下工程的build文件夾下可以發(fā)現(xiàn):

Paste_Image.png
打包不同內(nèi)容的module
打包不同內(nèi)容的module可以利用之前講過的variant或這個buildtypes來控制,這里就不說了,不明白的,可以回頭再去看一下結(jié)合上面的打包腳本沒有什么難度,然而還有一種需求,不是某個變量或者包名的更改,而是兩個版本中兩個文件的不同,我們可以試一下修改variant的方式來實(shí)現(xiàn),在app的build.gradle中:

修改結(jié)構(gòu)目錄:

Paste_Image.png
這樣編譯出來就會有兩個不同類型的apk了
防止打包錯誤
在這里已經(jīng)說完了所有與打包相關(guān)的東西了,在最后仍然加這一個標(biāo)題是交給大家如何防止項目開發(fā)者打包出錯,或者上傳包出錯后定位問題。
方法就是在打包的時候,生成一個記錄文件,在這個包中記錄打包時間,和當(dāng)前git的版本號:

以上工程中所用到的所有代碼,已經(jīng)上傳github
地址如下:
https://github.com/mymdeep/AndroidGradle
如有對groovy語法不清楚的看官,請看一下我的上一篇文章,groovy基礎(chǔ)知識:
http://m.itdecent.cn/p/b58b254d8f6e

