gradle配置全局变量
1.gradle的ext属性
ext属性是ExtensionAware类型的一个特殊的属性,本质是一个Map类型的变量。
ext属性可以伴随对应的ExtensionAware对象在构建的过程中被其他对象访问,例如你在rootProject中声明的ext中添加的内容,就可以在任何能获取到rootProject的地方访问这些属性。
在android的rootProject的build.gradle中,定义如下代码块
ext.commonConfig = [
minSdkVersion : 21,
targetSdkVersion : 26,
compileSdkVersion: 29,
versionName : "1.0.0",
versionCode : 1,
]
然后在模块下使用该数据,这里首先用def定义一个变量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.配置请求环境变量
在项目的build.gradle文件中,配置出开发,测试,正式环境的变量。
buildscript {
//配置3种环境
ext.isDev = 0
ext.isBeta = 1
ext.isRelease = 2
//当前打包环境
ext.curEnv = isRelease
}
在app模块下的build.gradle文件的android->defaultConfig代码块中,添加如下代码。
defaultConfig {
if (curEnv == isDev) {
manifestPlaceholders.put('APP_NAME', "开眼-开发")
} else if (curEnv == isBeta) {
manifestPlaceholders.put('APP_NAME', "开眼-测试")
} else if (curEnv == isRelease){
manifestPlaceholders.put('APP_NAME', "开眼-正式")
}
}
curEnv、isDev、isBeta、isRelease变量都是之前定义过的,能直接引用到。通过manifestPlaceholders注入APP_NAME的属性到manifest文件中,在menifest中设置application的名字为当前环境对应的名字,从而实现app名字为对应环境的名字,manifestPlaceholders 可以替换androidmanifest文件中的标签。这里添加:
android:label="${APP_NAME}"
在网络请求所属模块下的android->defaultConfig代码块中,像BuildConfig文件注入如下四个属性:
defaultConfig {
//将环境变量注入到buildConfig中
buildConfigField 'int', 'CUR_ENV', "$curEnv"
buildConfigField 'int', 'IS_DEV', "0"
buildConfigField 'int', 'IS_BETA', "1"
buildConfigField 'int', 'IS_RELEASE', "2"
}
经过编译之后就自动生成了该四个属性和值:
最后一步,根据配置的环境变量配置域名:
/** 开发服务器地址 */
private const val SERVER_ADDRESS_DEV = ""
/** 测试服务器地址 */
private const val SERVER_ADDRESS_BETA = ""
/** 正式服务器地址 */
private const val SERVER_ADDRESS_RELEASE = ""
/**
* 获取服务器域名
*/
fun getBaseUrl(): String? {
return when (BuildConfig.CUR_ENV) {
BuildConfig.IS_DEV -> {
ToastUtil.show("开发环境")
SERVER_ADDRESS_DEV
}
BuildConfig.IS_BETA -> {
ToastUtil.show("测试环境")
SERVER_ADDRESS_BETA
}
BuildConfig.IS_RELEASE -> {
ToastUtil.show("正式环境")
SERVER_ADDRESS_RELEASE
}
else -> ""
}
}
-
引入gradle插件
apply plugin: 插件名 引入插件以后相当于包含了该插件所有的任务类型、任务、属性等。
-
在gradle文件中引入独立gradle文件:
apply from: '../xxx.gradle'
-
读取gradle.properties文件中数据
示例:读取gradle.properties中一个属性值NET_TYPE=dev,用来对应当前安装包的环境类型。
//使用文件流读取properties数据
def getServer() {
def netType
Properties properties = new Properties() //使用Properties读取流文件
def file = file("../gradle.properties") // file() 创建一个Java中的File对象
if (file.canRead()) {
//可以读取到文件
properties.load(file.newInputStream())
if (properties != null) {
//文件读取成功
netType = properties.getProperty('NET_TYPE') //getProperty读取属性值
}
}
return netType
}
-
往该模块的BuildConfig文件注入属性和值
//需要三个参数 1.属性类型(String/int) 2.属性名 3.属性值
//String类型,需要加入转义的双引号才表示字符串,不然生成的变量没有双引号
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中生成了新的属性和值:
然后可以根据BuildConfig中类型来获取对应BaseUrl
/**
* 获取当前环境的域名
*/
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
}
}
-
自动配置签名信息
在app下的build.gradle文件的android{}中配置签名所需信息,可直接用gradle命令打包。
//签名配置
signingConfigs {
release {
keyAlias 'xxxx'
keyPassword 'xxx'
storeFile file('xxxx.jks')
storePassword 'xxxx'
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
-
多渠道配置,并将相关信息配置进apk名字
在app下的build.gradle文件中,配置一键化多渠道打包:
defaultConfig {
...
flavorDimensions "versionCode" //还需要配置多渠道打包code
}
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名称,带有渠道名称,时间戳,版本号,版本名称等信息
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${new Date().format("yyyy-MM-dd")}_${defaultConfig.versionName}_release.apk"
}
}
}
}
限制依赖条件为build类型
对于一些环境下,我们并不想在线上依赖某些库或者 「model」 ,如果是三方库,一般都会有 「relase」 下依赖的版本。当我们使用默认的 debugImplementation 和 releaseImplementation 进行依赖时,最终打包时是否会依赖其中,取决于我们 「使用的build命令中build类型是不是debug或者relase」。
debugImplementation project(":dev")
releaseImplementation project(":dev_noop")
排除传递的依赖项
开发中,我们经常会遇见依赖冲突,对于第三方库导致的依赖冲突,比较好解决,我们只需要使用 exclude 解决即可,如下所示:
dependencies {
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0") {
exclude group: 'androidx.lifecycle', module: 'lifecycle-process'
}
}
动态调整组件开关
对于一些组件,在 debug 开发时如果依赖,对我们的编译时间可能会有影响,那么此时,如果我们增加相应的开关控制,就会比较好:
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