[Gradle-11]动态修改版本名称和版本代码
作者:访客发布时间:2023-12-15分类:程序开发学习浏览:110
前言
有个读者问了一个比较有意思又很常见的问题,怎么修改版本名称和版本代码?
这位读者提问的方式也挺好,报错信息和尝试过的方式都提到了.
关于报错以及解决方案,正如上图我评论回复所说.
静态修改直接在build.gradle文件改就好了,动态修改还是有点意思的。
但是这种需求也比较常见,比如加上Git Commit id啊,时间戳啊等等,以便于区分,省的测试同学提了Bug搞半天是包不对...
那么本文就来带大家实践一下,以及探索有没有其他方式.
配置构建类型
我们可以通过配置不同的BuildType
,然后使用versionNameSuffix
、分别设置对应的版本名称后缀.
buildTypes {
debug{
versionNameSuffix "-测试包"
}
release {
versionNameSuffix "-正式包"
}
}
现在的版本名称和版本号:
defaultConfig {
versionCode 1
versionName "1.0"
}
调用看看有没有生效:
override fun onResume() {
super.onResume()
val packageInfo = applicationContext.packageManager.getPackageInfo(applicationContext.packageName, 0)
Log.wtf("yechaoa", "versionName = " + packageInfo.versionName)
Log.wtf("yechaoa", "versionCode = " + packageInfo.versionCode)
}
输出:
E versionName = 1.0-测试包
E versionCode = 1
生效是生效了,但是这种方式可以改版本名称、改不了版本代码、有一定局限性。
动态属性
这种呢,就是通过占位符的方式,原有的版本名称和版本代码不是写死的,通过动态获取的方式来设置,我们就可以打包脚本里加上版本名称的配置,以达到编译期动态修改的效果,这种方式在CI/CD
中比较常见.
先加两个方法来获取版本名称和版本代码:
def getVersionNameByProperty() {
def name
if (hasProperty("VersionName") && getProperty('VersionName') != null) {
name = getProperties().get('VersionName')
} else {
name = "2.0-default"
}
return name
}
def getVersionCodeByProperty() {
def code
if (hasProperty("VersionCode") && getProperties().get('VersionCode') != null) {
code = getProperties().get('VersionCode')
} else {
code = 2
}
return code
}
默认配置引用方法:
defaultConfig {
versionCode getVersionCodeByProperty()
versionName getVersionNameByProperty()
}
如上,正常点击按钮编译VersionName应该是“2.0-Default”,VersionCode应该是的2。
我们编译看下是不是符合预期:
E versionName = 2.0-default-测试包
E versionCode = 2
符合预期,而且加上了我们在构建类型里面设置的后缀“测试包”。
那么接下来再用命令执行试试:
./gradlew installDebug -PVersionName=2.0-property
这里只是加了-PVersionName,VerisonCode同理。
输出:
E versionName = 2.0-property-测试包
E versionCode = 2
可以看到,VersionName由“2.0-Default-测试包”变成“2.0-Property-测试包”了,我们的效果达到了。
变体
variants
是变体的意思,在构建中通常用来配置不同的版本、不同的环境等,比如多渠道打包,上面刚介绍的构建类型也是。
但这里要介绍的变体方式,跟构建类型的时间要晚一些,是在Configuration
阶段,也就是拿到所有的变种之后再去改。
变种能力是Gradle提供的,在安卓中对应的是applicationVariants
那就是。
首先遍历所有变体,然后通过风味拿到版本名称和版本代码,然后再赋值。
applicationVariants.configureEach { variant ->
def flavor = variant.mergedFlavor
flavor.versionName = '3.0'
flavor.versionCode = 3
}
结果编译报错:
Caused by: java.lang.RuntimeException: com.android.build.gradle.internal.crash.ExternalApiUsageException: com.android.builder.errors.EvalIssueException: versionName cannot be set on a mergedFlavor directly.
然后瞅了下源码,是MergedFlavor
里面抛出来的:
class MergedFlavor(
name: String,
private val _applicationId: Property<String>,
private val services: VariantServices
) : AbstractProductFlavor(name), InternalBaseVariant.MergedFlavor {
//...
override var versionCode: Int?
get() = super.versionCode
set(value) {
// calling setVersionCode results in a sync Error because the manifest merger doesn't pick
// up the change.
reportErrorWithWorkaround("versionCode", "versionCodeOverride", value)
}
override var versionName: String?
get() = super.versionName
set(value) {
// calling setVersionName results in a sync Error because the manifest merger doesn't pick
// up the change.
reportErrorWithWorkaround("versionName", "versionNameOverride", value)
}
private fun reportErrorWithWorkaround(
fieldName: String,
outputFieldName: String,
fieldValue: Any?
) {
val formattedFieldValue = if (fieldValue is String) {
""" + fieldValue + """
} else {
fieldValue.toString()
}
val message = """$fieldName cannot be set on a mergedFlavor directly.
|$outputFieldName can instead be set for variant outputs using the following syntax:
|android {
| applicationVariants.all { variant ->
| variant.outputs.each { output ->
| output.$outputFieldName = $formattedFieldValue
| }
| }
|}""".trimMargin()
services.issueReporter.reportError(IssueReporter.Type.GENERIC, message)
}
}
调用设置版本名称会导致同步错误,清单文件接收不到更新。
当然异常里面也给了解决方案,使用versionNameOverride
那就是。
applicationVariants.configureEach { variant ->
variant.outputs.each { output ->
if (variant.buildType.name == "debug") {
output.versionNameOverride = "3.0"
output.versionCodeOverride = 3
}
}
}
然后我们这里还把版本名称和版本代码升级了一下,再来试试。
输出:
E versionName = 3.0
E versionCode = 3
好的,这达到我们想要效果了。
总结
本文通过BuildType、属性、Variants三种方式介绍了动态修改版本代码和版本名称的方法,但是他们的时机却有不同。
- BuildType:有局限性,仅能修改版本名称、无法修改版本代码;
- 属性:使用比较方便,在云编译场景比较常见,本地的话可以写在打包脚本里面;
- 变种:比较彻底,能完全覆盖,而且也可以抽成插件、但是如果有云编译的话,会导致云编译的更改失效;
最后
以上即是本文介绍内容,学废了吗,写作不易,记得三连~
GitHub
Githeb.com/yechaoa/gra…
- 程序开发学习排行
-
- 1鸿蒙HarmonyOS:Web组件网页白屏检测
- 2HTTPS协议是安全传输,为啥还要再加密?
- 3HarmonyOS鸿蒙应用开发——数据持久化Preferences
- 4记解决MaterialButton背景颜色与设置值不同
- 5鸿蒙HarmonyOS实战-ArkUI组件(RelativeContainer)
- 6鸿蒙HarmonyOS实战-ArkUI组件(Stack)
- 7[Android][NDK][Cmake]一文搞懂Android项目中的Cmake
- 8Android广播如何解决Sending non-protected broadcast问题
- 9鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
- 最近发表
-
- WooCommerce最好的WordPress常用插件下载博客插件模块的相关产品
- 羊驼机器人最好的WordPress常用插件下载博客插件模块
- IP信息记录器最好的WordPress常用插件下载博客插件模块
- Linkly for WooCommerce最好的WordPress常用插件下载博客插件模块
- 元素聚合器Forms最好的WordPress常用插件下载博客插件模块
- Promaker Chat 最好的WordPress通用插件下载 博客插件模块
- 自动更新发布日期最好的WordPress常用插件下载博客插件模块
- WordPress官方最好的获取回复WordPress常用插件下载博客插件模块
- Img to rss最好的wordpress常用插件下载博客插件模块
- WPMozo为Elementor最好的WordPress常用插件下载博客插件模块添加精简版