Android Version Code Tricks

Zkusíme tuto možnost. Nejprve nastavíme aplikaci a jako výchozí versionCode uvedeme 1 a u všech variantních výstupů jej přepíšeme na 2:

Ale když se pak podíváme do souboru BuildConfig, uvidíme, že kód verze je stále nastaven na 1. Ačkoli když se podíváme do výsledného AndroidManifestu, uvidíme kód verze správně nastavený na 2.
Chybu nebo vlastnost? Pojďme zjistit, co se děje.

Uvnitř kódu se můžeme dostat ke kódu verze z BuildConfig.VERSION_CODE nebo z PackageManager.packageInfo.versionCode:

Po spuštění kódu v Logcatu uvidíme přesně to, co jsme pozorovali výše:

Důvod, proč k tomu dochází, je ten, že v nástrojích pro sestavení android gradle existují dvě samostatné úlohy pro generování souboru BuildConfig a pro zpracování AndroidManifest.

Podíváme-li se dovnitř GenerateBuildConfig, zjistíme, že vlastnost VERSION_CODE je generována z metody getVersionCode():

A že getVersionCode odkazuje na hodnotu uloženou v variantConfiguration:

Na rozdíl od generování BuildConfig v ProcessApplicationManifest vidíme, že kód verze se načítá z apkData.

Pokud zkontrolujeme variantConfiguration a apkData před a po nastavení kódu verze override:

Uvidíme, že hodnota uvnitř výstupních apkData byla změněna, i když původní hodnota v variantConfiguration zůstala stejná (podle očekávání):

Jak je uvedeno v tomto problému, je to provedeno záměrně z výkonnostních důvodů.

Závěr

Buďte opatrní, pokud používáte setVersionCodeOverride, protože můžete mít různé kódy verzí v BuildConfig a AndroidManifest.

Také podle dokumentace je doporučeným způsobem kontroly kódu verze přístup přes PackageManager, ne přes BuildConfig:

Ještě lepší je mít logiku verzování mimo build.gradle a poskytovat ji přes parametr gradle pomocí CI.

Také je moudrou volbou nespoléhat se příliš ve své codebase na BuildConfig.VERSION_CODE. Pro případy migrace je lepší zavést vlastní lokální verzování (jako se to dělá u SQL databází).

Happy coding!