概述
在日常開(kāi)發(fā)中,開(kāi)發(fā)項(xiàng)目的時(shí)候可能要在測(cè)試環(huán)境中開(kāi)發(fā),上線之后又要換一套環(huán)境,因?yàn)橐苊鉁y(cè)試環(huán)境和線上環(huán)境的數(shù)據(jù)互相混淆,在切換環(huán)境的時(shí)候你可能要更換域名,更換apk的簽名文件,更換第三方申請(qǐng)的key或是關(guān)閉日志等等
當(dāng)然這還是比較簡(jiǎn)單的情況,隨著項(xiàng)目規(guī)模的擴(kuò)大,要保證項(xiàng)目的可靠性,可能又要增加新環(huán)境,比如像預(yù)生產(chǎn)環(huán)境,給投資人展示項(xiàng)目又要用到演示環(huán)境,演示環(huán)境可能就要簡(jiǎn)化一些流程,在短時(shí)間內(nèi)給客戶展示核心功能,這不只是配置不一樣了,連很多代碼的實(shí)現(xiàn)邏輯流程都不一樣了
項(xiàng)目小的時(shí)候或許只需要寫(xiě)個(gè)清單去挨個(gè)替換掉,但項(xiàng)目一大不僅重復(fù)工作增加,并且還容易出錯(cuò),這時(shí)候就要用的gradle的多環(huán)境自動(dòng)化配置,保證切換環(huán)境的時(shí)候快捷安全;
相信大家都用過(guò)svn或是git等代碼管理工具,其實(shí)gradle多環(huán)境配置也屬于代碼管理工具,如果要區(qū)分他們有什么不同,那就是svn/git是屬于代碼縱向管理工具,gradle多環(huán)境是屬于代碼橫向管理工具
構(gòu)建多環(huán)境的兩種方式
1.buildTypes
buildTypes主要用于環(huán)境的區(qū)分,不同的環(huán)境采用不同的配置
可以在file->project structure去配置,選擇主項(xiàng)目,可以看到項(xiàng)目默認(rèn)有debug和release兩個(gè)環(huán)境,在這里配置可以顯示在主項(xiàng)目的builde.gradle的android{}下:

buildTypes的常用屬性:
minifyEnabled:是否開(kāi)啟混淆
debuggable:是否允許斷點(diǎn)調(diào)試
applicationIdSuffix:包名增加后綴
javaCompileOptions:配置Java編譯選項(xiàng)
jniDebuggable:此構(gòu)建類型是否配置為生成具有可調(diào)試本機(jī)代碼的APK
manifestPlaceholders manifest明示占位符
multiDexEnabled:是否限制方法數(shù)65535
name:生成的apk名字
proguardFiles:返回要使用的ProGuard配置文件。
shrinkResources:是否啟用未使用資源的收縮。默認(rèn)值為false
testCoverageEnabled:是否為此構(gòu)建類型啟用了測(cè)試覆蓋率。
versionNameSuffix:版本名稱后綴。
常用方法:
buildConfigField(type, name, value):向生成的BuildConfig類添加一個(gè)新字段,和buildTypes的常用屬性一樣,可以在BuildConfig中直接取到
consumerProguardFile(proguardFile):添加要包含在已發(fā)布的AAR中的proguard規(guī)則文件。
consumerProguardFiles(proguardFiles):添加要包含在已發(fā)布的AAR中的proguard規(guī)則文件。
externalNativeBuild(action):配置本機(jī)構(gòu)建選項(xiàng)。
initWith(that):從給定的構(gòu)建類型復(fù)制所有屬性。
proguardFile(proguardFile):添加一個(gè)新的ProGuard配置文件。
proguardFiles(files):添加新的ProGuard配置文件。
resValue(type, name, value):添加新生成的資源
setProguardFiles(proguardFileIterable):設(shè)置ProGuard配置文件。
initWith,比如你要新建一個(gè)預(yù)生產(chǎn)環(huán)境pre,這個(gè)環(huán)境大部分屬性都和release一樣,只有一個(gè)minifyEnabled屬性不相同,可以寫(xiě)成
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
signingConfig signingConfigs.release
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
signingConfig signingConfigs.debug
}
pre{
initWith release
minifyEnabled false
}
}
resValue是重新生成資源,比如我們?cè)赿ebug環(huán)境中使用resValue,如下
debug {
minifyEnabled false
signingConfig signingConfigs.debug
resValue "string", "AppName", "CustomName"
}
就可以在目錄app\build\generated\res\resValues\debug\values\gradleResValues.xml
中發(fā)現(xiàn)相應(yīng)的字段

2.Flavors
第二種構(gòu)建方式Flavors其實(shí)和buildTypes在用法上差別不大,比如Flavors的一些屬性,如buildConfigField,manifestPlaceholders,applicationIdSuffix等等,都buildTypes的用法都一樣,都可以在BuildConfig中直接獲取到,同樣也是配置在build.gradle的android{}下
如果buildTypes和Flavors完全一樣,也就沒(méi)必要設(shè)計(jì)出來(lái)了,最大的不同就是Flavors可以配置不同的代碼,可以配置不同的assets資源文件和res資源文件,而這些只用配置的方式不能實(shí)現(xiàn)
來(lái)實(shí)現(xiàn)一個(gè)例子,比如在項(xiàng)目中測(cè)試的時(shí)候需要屏蔽一些登錄流程,這時(shí)候不同環(huán)境下的LoginActivity類實(shí)現(xiàn)就不一樣,在比如,像第三方SDK mob分享,就要在assets文件中定義分享平臺(tái)的key,不用環(huán)境需要不同的key,那么,建立兩個(gè)Flavors就可以實(shí)現(xiàn)不同環(huán)境先登錄流程的不同和sharekey的不同
打開(kāi)file->project structure->Build Variants->Flavors,選中主項(xiàng)目,建立login和share兩個(gè)Flavors
productFlavors {
login {
}
share {
}
}
加上之前建立的debug,release和pre環(huán)境,我們查看Builde Variant就發(fā)現(xiàn)有6個(gè)環(huán)境了(2*3)

完成之后,之前的debug,release和pre環(huán)境都能分別實(shí)現(xiàn)兩種不同登錄邏輯和sharekey的配置
替換src的代碼
接下來(lái)就要在不同環(huán)境配置登錄邏輯
在原有的目錄中,有一個(gè)LoginActivity

要在login的Flavors環(huán)境中替換LoginActivity,首先要在src目錄下建立一個(gè)和Flavors環(huán)境名字一樣的目錄login

因?yàn)橐鎿Q掉住項(xiàng)目中的LoginActivity,所以就要建立和LoginActivity相同的路徑,LoginActivity的路徑是java.com.dj.combat.multienvironment.LoginActivity,所以在新建的login目錄下也要如此,建好之后就變成了這樣

在LoginActivity中加入你的新邏輯就可以了
替換assets資源文件
替換assets資源文件和src里面的代碼沒(méi)什么區(qū)別,在主環(huán)境中,assets和java是同一目錄

我們?cè)趧偛沤⒌膌ogin環(huán)境里面加入assets也是同樣的


同樣的,res里面的文件也可以用此方法實(shí)現(xiàn)替換