4

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.

João Zão
  • 170
  • 1
  • 11
  • you still could set different version codes there - but have to assign them differently. when overriding version code, this obviously would be the `BuildConfig.VERSION_CODE` then. – Martin Zeitler Sep 25 '18 at 16:51
  • The `BuildConfig.VERSION_CODE` doesn't reflect the ` `output.versionCodeOverride = 40805`. Instead the version code in the auto-generated BuildConfig.java is always `BuildConfig.VERSION_CODE=-1`. Which is not what happened before when we used the `variant.mergedFlavor.versionCode =40805` than the auto-generated was `BuildConfig.VERSION_CODE=40805` – João Zão Sep 25 '18 at 16:56
  • I'm using the `40805` as example, assigning different versionCodes to `output.versionCodeOverride ` is not a problem. – João Zão Sep 25 '18 at 17:02
  • It should be `variant.outputs.all` instead of `variant.outputs.each` ever since Android Gradle Plugin 3.0.0, can you confirm that works? – Eugen Pechanec Sep 25 '18 at 19:45
  • Unfortunately that doesn't work either. – João Zão Sep 25 '18 at 19:51

2 Answers2

3

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.

Community
  • 1
  • 1
Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
  • Thanks, didn't notice it was already raised in issue tracker and labeled as intended. I dropped here the question exactly because I didn't want to rely on packageinfo. I was looking for smarter solutions than mine which is adding a new buildconfigfield something like this `variant.buildConfigField('int','OVERRIDDEN_VERSION_CODE', "${versionCodeOverride}")`. – João Zão Sep 25 '18 at 20:47
2

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.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • I'm doing like you posted. Did you tried to see what was the `BuildConfig.VERSION_CODE` generated in `BuildConfig.java`? It compiles of course (that wasn't the problem) but I get `BuildConfig.VERSION_CODE=-1` in the `BuildConfig.java` – João Zão Sep 25 '18 at 17:16
  • The problem I'm facing is not to configure the versioning as you posted in the example but because with this new way of assign the version code for each variant, the version code is not being reflected in the BuildConfig.java more specifically the `BuildConfig.VERSION_CODE`. So I can't rely on the generated `BuildConfig.VERSION_CODE`. – João Zão Sep 25 '18 at 17:29
  • @JoãoZão a value of `-1` hints for, that nothing had been set at all - neither per default, nor over-riden. there also would be config `buildConfigField`, which lets one add custom fields - and also config `manifestPlaceholders`, which both could be used. the question lacks the `build.gradle`, therefore it is quite unclear, why the value is `-1`. – Martin Zeitler Sep 25 '18 at 18:34
  • I know what the `-1` means. The problem is that I can't achieve the same with `versionCodeOverride` as I was achieving with `mergedFlavor.versionCode` when generating the `BuildConfig.VERSION_CODE`. I made a video showing a simple example of what I asked. https://vimeo.com/291770418 – João Zão Sep 25 '18 at 19:05
  • it's only logical to use the same version-code for all flavors (which issue `37008496` also confirms - because this would affect update behavior). adding `BuildConfig.VERSION_FLAVOR` might still be the best option available, to have two integer values, for version code & version flavor. – Martin Zeitler Sep 25 '18 at 20:25
  • That's not correct if you use flavours to build completely different applications (with different applicationIds) – João Zão Sep 25 '18 at 20:37
  • @JoãoZão and what has this (still questionable packaging concept) to do, with attempting to assign different version-codes to them? it clearly reads `Status: Won't Fix (Intended Behavior)`, since at least 2014. currently just more of that becomes enforced. – Martin Zeitler Sep 25 '18 at 20:51
  • You said that is only logic to use the same version-code for all flavours. I don't agree with that since you can use flavours to build completely different applications with different applicationIds which can and most likely have different version codes. Btw thanks for all the quick responses. – João Zão Sep 25 '18 at 20:57
  • 1
    you are right by saying "while the reason for this isn't build-tools 3.2.0, but it's Gradle 4.6.". I had to make use of `output.versionCodeOverride ` in gradle4.6. However before updating to AGP 3.2 we could keep setting the `versionCode` through `mergedFlavor.versionCode` and the `BuildConfig.VERSION_CODE` kept being updated correctly. The "problem" is that after updating to AGP 3.2 you can't use `mergedFlavor.versionCode` anymore and the `BuildConfig.VERSION_CODE` is not being updated by `output.versionCodeOverride `. This happens for a good reason so I'm happy to adapt to it. – João Zão Sep 26 '18 at 00:54
  • @JoãoZão, Why they did like that? Is there any reason? – Nigam Patro Mar 07 '19 at 09:01
  • @Martin Zeitler I have build.gradle version 4.10, not 4.6. But, why it is like that? – Nigam Patro Mar 07 '19 at 09:14