gradle配置技巧

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Gradle配置最佳实践 本文会不定期更新,推荐watch下项目。如果喜欢请star,如果觉得有纰漏请提交issu...
    Solang阅读 1,688评论 0 4
  • 为方便在不同module中设置版本号等配置信息,可以通过配置全局变量来统一所有module的公共配置信息。设置方法...
    CarlWu_S阅读 6,906评论 1 2
  • 为方便在不同module中设置版本号等配置信息,可以通过配置全局变量来统一所有module的公共配置信息。设置方法...
    zheting阅读 2,902评论 1 1
  • 上一篇文章中详细介绍了module中build.gradle文件的属性和配置,今天详细讲解一下我在自己的应用中主...
    sakasa阅读 1,094评论 0 1
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaoyanj...
    勤奋的pangdunhu阅读 2,157评论 0 1