android-gradle set versionNameOverride 未在 BuildConfig 中设置 versionName.java

android-gradle set versionNameOverride does not set versionName in BuildConfig.java

提问人:A1m 提问时间:2/28/2019 更新时间:5/16/2019 访问量:1301

问:

我们有一个 和 buildType,并希望将 and 设置为常量值,否则,即使没有更改代码,每个构建也会重新打包 apk。releasedebugversionCodeversionNamedebug

因此,我们设置了一个固定的默认值,然后为特定的 buildType 覆盖它:versionCode

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 BuildConfig1/"1.0"versionNumber

显然是在配置时生成的,而不是在项目构建时生成的,因此它无法知道所选的变体。如何处理这个问题?BuildConfig.java

我们包含时间戳,所以每个versionCode都是不同的。我尝试翻转语句,以便调试版本每次都会显示不同的 versionCode 和 versionName,这对我们来说很好。getAppVersionCode()

android {
    defaultConfig {
        versionCode getAppVersionName()
        versionName getAppVersionCode()
    }

    applicationVariants.all { variant ->
        if (variant.buildType.isDebuggable()) {
            variant.outputs.each { output ->
                output.versionCodeOverride = 1
                output.versionNameOverride = "1.0"                
            }
        }
    }
}

我们之所以首先有一个固定的调试,是因为我们不想为每次代码更改重新构建所有子模块。对于第二种变体,即使我们通过所有子模块重新构建调试构建设置了固定版本。在 Android Studio 3.0 之前,这行得通,但现在不再行了。请指教。versionCodeversionNumberoutput.versionCodeOverride = 1

android-gradle-plugin android-studio-3.0

评论


答:

2赞 Brian Acker 5/16/2019 #1

如您所见,它们是在配置时设置的自动配置字段,不幸的是,使用 gradle 脚本设置输出覆盖值不受影响。BuildConfig.VERSION_NAMEBuildConfig.VERSION_CODE

因为它们是自动配置字段,所以也不能通过 gradle 脚本直接更改它们。幸运的是,在使用您的方法时,有一些方法可以解决这个问题:

1) 从包管理器获取要显示的真实版本值: 与其打电话,不如打电话,或者你需要在应用程序中显示它们,打电话BuildConfig.VERSION_NAMEBuildConfig.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
        }

这将返回您为所选变体设置的版本值,即使 BuildConfig 字段默认为“1.0”/1output.versionCodeOverride

2) 为应用版本添加自己的 BuildConfig 字段 如果您确实希望可以从 BuildConfig 访问版本名称,则可以在设置输出覆盖值时构建其他配置字段。只要确保你不使用 和 的自动字段名称:VERSION_NAMEVERSION_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

评论

0赞 A1m 5/16/2019
现在,我们通过为两种不同的方案迁移到另一种构建风格来修复此问题。不过,您的解决方案看起来不错,谢谢:)