BuildConfig.VersionCode is not reflecting the actu

2019-07-18 18:58发布

After updating to AGP(Android Gradle Plugin) 3.2.0 we can't set versionCode directly on a mergedFlavor. If we do so we get this useful warning:

versionCode cannot be set on a mergedFlavor directly.
versionCodeOverride can instead be set for variant outputs using the following syntax:
android {
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.versionCodeOverride = 40805
        }
    }
}

After this change everything works fine besides one little thing. The auto-generated BuildConfig.VERSION_CODE doesn't reflect the version code from output.versionCodeOverride = 40805.

Before AGP 3.2.0 we could set the versionCode dynamically through:

applicationVariants.all { v ->
        v.mergedFlavor.versionCode = 40805 // 40805 is hardcoded as an example but it is archived dynamically.
    }

And the version code reflected in BuildConfig.VERSION_CODE (this is very handy) and I would like to archive the same with AGP 3.2.0.

I know I could workaround this by creating a custom build config field for this like variant.buildConfigField('int', 'OVERRIDDEN_VERSION_CODE', "${versionCodeOverride}") and this will generate the BuildConfig.OVERRIDDEN_VERSION_CODE with the versionCode I override. Archiving the same as I was when using the AGP version bellow 3.2.0 by setting the versionCode through mergedFlavor.versionCode = 40805 but I don't like this kind of workarounds.

Is there any way to have the output.versionCodeOverride = 40805 being reflecting in the auto-generated BuildConfig.VERSION_CODE?

PS: If we set the versionCode directly in the specific flavor it will work as expected but that's not what I want to know :)

UPDATE

Found a similar question(with a well described use case) and considering the discussions we had I could give a better answer here.

2条回答
Evening l夕情丶
2楼-- · 2019-07-18 19:05

the order of instructions is important there ...

String versionName = version.versionName
int versionCode = version.versionCode

android {
    applicationVariants.all { variant ->

        // to be removed here:
        // variant.mergedFlavor.versionCode = versionCode

        variant.outputs.each { output ->

            // and to be added here:
            output.versionNameOverride = versionName
            output.versionCodeOverride = versionCode
        }
    }
}

the documentation for Build multiple APKs explain it, below "Configure versioning".

while the reason for this isn't build-tools 3.2.0, but it's Gradle 4.6.

查看更多
爷的心禁止访问
3楼-- · 2019-07-18 19:09

To recap, the problem isn't the version code override not being applied at all, it's just that BuildConfig.VERSION_CODE does not pick up the override value.

This has been labeled as intended behavior in the official issue tracker: https://issuetracker.google.com/issues/37008496

One of the comments explains why and suggests defining versionCode in a flavor instead of the defaultConfig:

If we made a different buildconfig.java per output then we'd also need to run javac/proguard/jacoco/dex for each split and we'd lose the improvement in build [time].

If this is critical to you, then don't use splits and use flavors instead, but we'll get much slower build time.

If you don't want to alter your curent setup you might want to read the version code from the manifest instead. All you need is a context:

val versionCode = context.packageManager.getPackageInfo(context.packageName, 0).versionCode

You should cache the value as getting package info is a non-trivial operation.

The same applies to version name.

查看更多
登录 后发表回答