admin管理员组文章数量:1550284
【Gradle
前言
有个读者问了一个比较有意思又很常见的问题,怎么修改VersionName和VersionCode?
这位读者提问的方式也挺好,报错信息和尝试过的方式都提到了。
关于报错以及解决方案,正如上图我评论回复所说。
静态修改直接在build.gradle文件改就好了,动态修改还是有点意思的。
但是这种需求也比较常见,比如加上git commit id啊,时间戳啊等等,以便于区分,省的测试同学提了bug搞半天是包不对…
那么本文就来带大家实践一下,以及探索有没有其他方式。
配置BuildType
我们可以通过配置不同的BuildType
,然后使用versionNameSuffix
,分别设置对应的版本名称后缀。
buildTypes {debug{versionNameSuffix "-测试包"}release {versionNameSuffix "-正式包"}}
现在的版本名称和版本号:
defaultConfig {versionCode 1versionName "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
生效是生效了,但是这种方式可以改versionName,改不了versionCode,有一定局限性。
动态Property
这种呢,就是通过占位符的方式,原有的versionName和versionCode不是写死的,通过动态获取的方式来设置,我们就可以打包脚本里加上VersionName的配置,以达到编译期动态修改的效果,这种方式在CI/CD
中比较常见。
先加两个方法来获取versionName和versionCode:
def getVersionNameByProperty() {def nameif (hasProperty("VersionName") && getProperty('VersionName') != null) {name = getProperties().get('VersionName')} else {name = "2.0-default"}return name
}def getVersionCodeByProperty() {def codeif (hasProperty("VersionCode") && getProperties().get('VersionCode') != null) {code = getProperties().get('VersionCode')} else {code = 2}return code
}
defaultConfig引用方法:
defaultConfig {versionCode getVersionCodeByProperty()versionName getVersionNameByProperty()}
如上,正常点击按钮编译versionName应该是"2.0-default",versionCode应该是的2。
我们编译看下是不是符合预期:
E versionName = 2.0-default-测试包E versionCode = 2
符合预期,而且加上了我们在buildType里面设置的后缀“测试包”。
那么接下来再用命令执行试试:
./gradlew installDebug -PVersionName=2.0-property
这里只是加了-PVersionName,VerisonCode同理。
输出:
E versionName = 2.0-property-测试包E versionCode = 2
可以看到,versionName由「2.0-default-测试包」变成「2.0-property-测试包」了,我们的效果达到了。
Variants
variants
是变体的意思,在构建中通常用来配置不同的版本、不同的环境等,比如多渠道打包,上面刚介绍的buildType也是。
但这里要介绍的variants方式,跟buildType的时间要晚一些,是在Configuration
阶段,也就是拿到所有的variants之后再去改。
variants能力是Gradle提供的,在Android中对应的是applicationVariants
。
首先遍历所有variants,然后通过Flavor拿到versionName和versionCode,然后再赋值。
applicationVariants.configureEach { variant ->def flavor = variant.mergedFlavorflavor.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.versionCodeset(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.versionNameset(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)}
}
调用setVersionName会导致同步错误,清单文件接收不到更新。
当然异常里面也给了解决方案,使用versionNameOverride
。
applicationVariants.configureEach { variant ->variant.outputs.each { output ->if (variant.buildType.name == "debug") {output.versionNameOverride = "3.0"output.versionCodeOverride = 3}}}
然后我们这里还把versionName和versionCode升级了一下,再来试试。
输出:
E versionName = 3.0E versionCode = 3
ok,这达到我们想要效果了。
总结
本文通过BuildType、Property、Variants三种方式介绍了动态修改VersionCode和VersionName的方法,但是他们的时机却有不同。
- BuildType:有局限性,仅能修改VersionName,无法修改VersionCode;
- Property:使用比较方便,在云编译场景比较常见,本地的话可以写在打包脚本里面;
- Variants:比较彻底,能完全覆盖,而且也可以抽成Plugin,但是如果有云编译的话,会导致云编译的更改失效;
最后
以上即是本文介绍内容,学废了吗,写作不易,记得三连~
GitHub
本文标签: Gradle
版权声明:本文标题:【Gradle 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1717067626a531545.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论