gradle配置全局變量
1.gradle的ext屬性
ext屬性是ExtensionAware類型的一個(gè)特殊的屬性,本質(zhì)是一個(gè)Map類型的變量。
ext屬性可以伴隨對(duì)應(yīng)的ExtensionAware對(duì)象在構(gòu)建的過程中被其他對(duì)象訪問,例如你在rootProject中聲明的ext中添加的內(nèi)容,就可以在任何能獲取到rootProject的地方訪問這些屬性。
在android的rootProject的build.gradle中,定義如下代碼塊
ext.commonConfig = [
minSdkVersion : 21,
targetSdkVersion : 26,
compileSdkVersion: 29,
versionName : "1.0.0",
versionCode : 1,
]
然后在模塊下使用該數(shù)據(jù),這里首先用def定義一個(gè)變量ext = rootProject.ext.commonConfig
def ext = rootProject.ext.commonConfig
android {
compileSdkVersion ext.compileSdkVersion
defaultConfig {
applicationId "com.example.mvvmframe"
minSdkVersion ext.minSdkVersion
targetSdkVersion ext.targetSdkVersion
versionCode ext.versionCode
versionName ext.versionName
}
}
2.配置請(qǐng)求環(huán)境變量
在項(xiàng)目的build.gradle文件中,配置出開發(fā),測(cè)試,正式環(huán)境的變量。
buildscript {
//配置3種環(huán)境
ext.isDev = 0
ext.isBeta = 1
ext.isRelease = 2
//當(dāng)前打包環(huán)境
ext.curEnv = isRelease
}
在app模塊下的build.gradle文件的android->defaultConfig代碼塊中,添加如下代碼。
defaultConfig {
if (curEnv == isDev) {
manifestPlaceholders.put('APP_NAME', "開眼-開發(fā)")
} else if (curEnv == isBeta) {
manifestPlaceholders.put('APP_NAME', "開眼-測(cè)試")
} else if (curEnv == isRelease){
manifestPlaceholders.put('APP_NAME', "開眼-正式")
}
}
curEnv、isDev、isBeta、isRelease變量都是之前定義過的,能直接引用到。通過manifestPlaceholders注入APP_NAME的屬性到manifest文件中,在menifest中設(shè)置application的名字為當(dāng)前環(huán)境對(duì)應(yīng)的名字,從而實(shí)現(xiàn)app名字為對(duì)應(yīng)環(huán)境的名字,manifestPlaceholders 可以替換androidmanifest文件中的標(biāo)簽。這里添加:
android:label="${APP_NAME}"
在網(wǎng)絡(luò)請(qǐng)求所屬模塊下的android->defaultConfig代碼塊中,像BuildConfig文件注入如下四個(gè)屬性:
defaultConfig {
//將環(huán)境變量注入到buildConfig中
buildConfigField 'int', 'CUR_ENV', "$curEnv"
buildConfigField 'int', 'IS_DEV', "0"
buildConfigField 'int', 'IS_BETA', "1"
buildConfigField 'int', 'IS_RELEASE', "2"
}
經(jīng)過編譯之后就自動(dòng)生成了該四個(gè)屬性和值:

最后一步,根據(jù)配置的環(huán)境變量配置域名:
/** 開發(fā)服務(wù)器地址 */
private const val SERVER_ADDRESS_DEV = ""
/** 測(cè)試服務(wù)器地址 */
private const val SERVER_ADDRESS_BETA = ""
/** 正式服務(wù)器地址 */
private const val SERVER_ADDRESS_RELEASE = ""
/**
* 獲取服務(wù)器域名
*/
fun getBaseUrl(): String? {
return when (BuildConfig.CUR_ENV) {
BuildConfig.IS_DEV -> {
ToastUtil.show("開發(fā)環(huán)境")
SERVER_ADDRESS_DEV
}
BuildConfig.IS_BETA -> {
ToastUtil.show("測(cè)試環(huán)境")
SERVER_ADDRESS_BETA
}
BuildConfig.IS_RELEASE -> {
ToastUtil.show("正式環(huán)境")
SERVER_ADDRESS_RELEASE
}
else -> ""
}
}
-
引入gradle插件
apply plugin: 插件名 引入插件以后相當(dāng)于包含了該插件所有的任務(wù)類型、任務(wù)、屬性等。
-
在gradle文件中引入獨(dú)立gradle文件:
apply from: '../xxx.gradle'
-
讀取gradle.properties文件中數(shù)據(jù)
示例:讀取gradle.properties中一個(gè)屬性值NET_TYPE=dev,用來(lái)對(duì)應(yīng)當(dāng)前安裝包的環(huán)境類型。
//使用文件流讀取properties數(shù)據(jù)
def getServer() {
def netType
Properties properties = new Properties() //使用Properties讀取流文件
def file = file("../gradle.properties") // file() 創(chuàng)建一個(gè)Java中的File對(duì)象
if (file.canRead()) {
//可以讀取到文件
properties.load(file.newInputStream())
if (properties != null) {
//文件讀取成功
netType = properties.getProperty('NET_TYPE') //getProperty讀取屬性值
}
}
return netType
}
-
往該模塊的BuildConfig文件注入屬性和值
//需要三個(gè)參數(shù) 1.屬性類型(String/int) 2.屬性名 3.屬性值
//String類型,需要加入轉(zhuǎn)義的雙引號(hào)才表示字符串,不然生成的變量沒有雙引號(hào)
buildConfigField 'String', 'IS_DEV', "\"dev\""
buildConfigField 'String', 'IS_BETA', "\"beta\""
buildConfigField 'String', 'IS_RELEASE', "\"release\""
buildConfigField 'String', 'NET_TYPE', "\""+getServer()+"\"" //net_type讀取properties中NET_TYPE值
在BuildConfig中生成了新的屬性和值:

然后可以根據(jù)BuildConfig中類型來(lái)獲取對(duì)應(yīng)BaseUrl
/**
* 獲取當(dāng)前環(huán)境的域名
*/
fun getBaseUrl(): String {
return when (BuildConfig.NET_TYPE) {
BuildConfig.IS_DEV -> {
SERVER_ADDRESS_DEV
}
BuildConfig.IS_BETA -> {
SERVER_ADDRESS_BETA
}
BuildConfig.IS_RELEASE -> {
SERVER_ADDRESS_RELEASE
}
else -> SERVER_ADDRESS_DEV
}
}
-
自動(dòng)配置簽名信息
在app下的build.gradle文件的android{}中配置簽名所需信息,可直接用gradle命令打包。
//簽名配置
signingConfigs {
release {
keyAlias 'xxxx'
keyPassword 'xxx'
storeFile file('xxxx.jks')
storePassword 'xxxx'
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
-
多渠道配置,并將相關(guān)信息配置進(jìn)apk名字
在app下的build.gradle文件中,配置一鍵化多渠道打包:
defaultConfig {
...
flavorDimensions "versionCode" //還需要配置多渠道打包c(diǎn)ode
}
productFlavors {
yingyongbao {}
qh360 {}
xiaomi {}
vivo {}
oppo {}
huawei {}
}
productFlavors.all { flavor->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
buildConfigField 'String', 'PLAT_FORM', "\"${name}\""
}
buildTypes {
release {
//通過Gradle生成apk名稱,帶有渠道名稱,時(shí)間戳,版本號(hào),版本名稱等信息
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${new Date().format("yyyy-MM-dd")}_${defaultConfig.versionName}_release.apk"
}
}
}
}
限制依賴條件為build類型
對(duì)于一些環(huán)境下,我們并不想在線上依賴某些庫(kù)或者 「model」 ,如果是三方庫(kù),一般都會(huì)有 「relase」 下依賴的版本。當(dāng)我們使用默認(rèn)的 debugImplementation 和 releaseImplementation 進(jìn)行依賴時(shí),最終打包時(shí)是否會(huì)依賴其中,取決于我們 「使用的build命令中build類型是不是debug或者relase」。
debugImplementation project(":dev")
releaseImplementation project(":dev_noop")
排除傳遞的依賴項(xiàng)
開發(fā)中,我們經(jīng)常會(huì)遇見依賴沖突,對(duì)于第三方庫(kù)導(dǎo)致的依賴沖突,比較好解決,我們只需要使用 exclude 解決即可,如下所示:
dependencies {
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0") {
exclude group: 'androidx.lifecycle', module: 'lifecycle-process'
}
}
動(dòng)態(tài)調(diào)整組件開關(guān)
對(duì)于一些組件,在 debug 開發(fā)時(shí)如果依賴,對(duì)我們的編譯時(shí)間可能會(huì)有影響,那么此時(shí),如果我們?cè)黾酉鄳?yīng)的開關(guān)控制,就會(huì)比較好:
buildscript {
ext.enableBooster = flase
ext.enableBugly = flase
if (enableBooster)
classpath "com.didiglobal.booster:booster-gradle-plugin:$booster_version"
}
代碼配置地址
參考 https://blog.csdn.net/huangxiaoguo1/article/details/103618209
https://www.bilibili.com/video/BV14541137MV?p=5&spm_id_from=pageDriver
https://mp.weixin.qq.com/s/ZbakWNlT_bYbhtfFx0-Lnw