android-gradle set versionNameOverride 不在 BuildConfig.java 中设置 versionName
android-gradle set versionNameOverride does not set versionName in BuildConfig.java
我们有一个 release
和 debug
buildType,并希望将 versionCode
和 versionName
设置为 debug
的常量值,否则,每个构建重新打包 apk,即使没有代码更改。
所以我们设置了一个固定的默认值 versionCode
并稍后为特定的 buildType 覆盖它:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.gradletest"
minSdkVersion 28
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
applicationVariants.all { variant ->
if (!variant.buildType.isDebuggable()) {
variant.outputs.each { output ->
output.versionCodeOverride = getAppVersionCode()
output.versionNameOverride = getAppVersionName()
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.debug
debuggable true
}
}
}
虽然这适用于 apk,但不幸的是生成的 class BuildConfig
始终具有默认的 1/"1.0"
值。我们按照 popular answer 建议从应用程序中读取并显示 versionNumber
。
显然 BuildConfig.java
是在配置时生成的,而不是在项目构建时生成的,因此它无法知道所选择的变体。如何处理?
我们的 getAppVersionCode()
包含时间戳,因此每个版本代码都不同。我尝试翻转语句,以便调试版本每次都会显示不同的 versionCode 和 versionName,这对我们来说很好。
android {
defaultConfig {
versionCode getAppVersionName()
versionName getAppVersionCode()
}
applicationVariants.all { variant ->
if (variant.buildType.isDebuggable()) {
variant.outputs.each { output ->
output.versionCodeOverride = 1
output.versionNameOverride = "1.0"
}
}
}
}
我们首先有一个固定调试 versionCode
的原因是我们不想为每次代码更改重建所有子模块。对于第二个变体,即使我们通过 output.versionCodeOverride = 1
为调试构建设置了固定的 versionNumber
,所有子模块都由 Android Studio 重建。在 Android Studio 3.0 之前,此方法有效但不再有效。请指教
正如您所注意到的,BuildConfig.VERSION_NAME
和 BuildConfig.VERSION_CODE
是在配置时设置的自动配置字段,遗憾的是不受使用 gradle 脚本设置输出覆盖值的影响。
因为它们是自动配置字段,它们也不能通过 gradle 脚本直接更改。幸运的是,使用您的方法时有一些解决方法:
1) 从包管理器中获取要显示的真实版本值:
不要在需要在应用程序中显示它们的地方调用 BuildConfig.VERSION_NAME
和 BuildConfig.VERSION_CODE
,而是调用
val versionName: String = context.packageManager.getPackageInfo(context.packageName, 0).versionName
val versionCode: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
context.packageManager.getPackageInfo(context.packageName, 0).longVersionCode.toInt()
} else {
context.packageManager.getPackageInfo(context.packageName, 0).versionCode
}
这将 return 您通过 output.versionCodeOverride
为所选变体设置的版本值,即使 BuildConfig 字段默认为“1.0”/1
2) 为应用程序版本添加您自己的 BuildConfig 字段
如果您确实希望可以从 BuildConfig 访问版本名称,则可以在设置输出覆盖值时构建额外的配置字段。请确保您不使用 VERSION_NAME
和 VERSION_CODE
:
的自动字段名称
android {
...
applicationVariants.all { variant ->
if (variant.buildType.isDebuggable()) {
variant.outputs.each { output ->
output.versionCodeOverride = 1
output.versionNameOverride = "1.0"
}
variant.buildConfigField("String", "REAL_VERSION_NAME", "\"${getAppVersionName()}\"")
variant.buildConfigField("Int", "REAL_VERSION_CODE", ${getAppVersionCode()})
}
}
}
然后使用
访问
val versionName: String = BuildConfig.REAL_VERSION_NAME
val versionCode: Int = BuildConfig.REAL_VERSION_CODE
我们有一个 release
和 debug
buildType,并希望将 versionCode
和 versionName
设置为 debug
的常量值,否则,每个构建重新打包 apk,即使没有代码更改。
所以我们设置了一个固定的默认值 versionCode
并稍后为特定的 buildType 覆盖它:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.gradletest"
minSdkVersion 28
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
applicationVariants.all { variant ->
if (!variant.buildType.isDebuggable()) {
variant.outputs.each { output ->
output.versionCodeOverride = getAppVersionCode()
output.versionNameOverride = getAppVersionName()
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.debug
debuggable true
}
}
}
虽然这适用于 apk,但不幸的是生成的 class BuildConfig
始终具有默认的 1/"1.0"
值。我们按照 popular answer 建议从应用程序中读取并显示 versionNumber
。
显然 BuildConfig.java
是在配置时生成的,而不是在项目构建时生成的,因此它无法知道所选择的变体。如何处理?
我们的 getAppVersionCode()
包含时间戳,因此每个版本代码都不同。我尝试翻转语句,以便调试版本每次都会显示不同的 versionCode 和 versionName,这对我们来说很好。
android {
defaultConfig {
versionCode getAppVersionName()
versionName getAppVersionCode()
}
applicationVariants.all { variant ->
if (variant.buildType.isDebuggable()) {
variant.outputs.each { output ->
output.versionCodeOverride = 1
output.versionNameOverride = "1.0"
}
}
}
}
我们首先有一个固定调试 versionCode
的原因是我们不想为每次代码更改重建所有子模块。对于第二个变体,即使我们通过 output.versionCodeOverride = 1
为调试构建设置了固定的 versionNumber
,所有子模块都由 Android Studio 重建。在 Android Studio 3.0 之前,此方法有效但不再有效。请指教
正如您所注意到的,BuildConfig.VERSION_NAME
和 BuildConfig.VERSION_CODE
是在配置时设置的自动配置字段,遗憾的是不受使用 gradle 脚本设置输出覆盖值的影响。
因为它们是自动配置字段,它们也不能通过 gradle 脚本直接更改。幸运的是,使用您的方法时有一些解决方法:
1) 从包管理器中获取要显示的真实版本值:
不要在需要在应用程序中显示它们的地方调用 BuildConfig.VERSION_NAME
和 BuildConfig.VERSION_CODE
,而是调用
val versionName: String = context.packageManager.getPackageInfo(context.packageName, 0).versionName
val versionCode: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
context.packageManager.getPackageInfo(context.packageName, 0).longVersionCode.toInt()
} else {
context.packageManager.getPackageInfo(context.packageName, 0).versionCode
}
这将 return 您通过 output.versionCodeOverride
为所选变体设置的版本值,即使 BuildConfig 字段默认为“1.0”/1
2) 为应用程序版本添加您自己的 BuildConfig 字段
如果您确实希望可以从 BuildConfig 访问版本名称,则可以在设置输出覆盖值时构建额外的配置字段。请确保您不使用 VERSION_NAME
和 VERSION_CODE
:
android {
...
applicationVariants.all { variant ->
if (variant.buildType.isDebuggable()) {
variant.outputs.each { output ->
output.versionCodeOverride = 1
output.versionNameOverride = "1.0"
}
variant.buildConfigField("String", "REAL_VERSION_NAME", "\"${getAppVersionName()}\"")
variant.buildConfigField("Int", "REAL_VERSION_CODE", ${getAppVersionCode()})
}
}
}
然后使用
访问val versionName: String = BuildConfig.REAL_VERSION_NAME
val versionCode: Int = BuildConfig.REAL_VERSION_CODE