Trucchi per il codice di versione Android

Proviamo questa opzione. Per prima cosa imposteremo l’app e forniremo 1 come versionCode predefinito e lo sovrascriveremo a 2 per tutte le varianti in uscita:

Ma poi se guardiamo all’interno del file BuildConfig vedremo che il codice di versione è ancora impostato su 1. Se invece guardiamo nel risultante AndroidManifest vedremo il codice di versione correttamente impostato su 2.
Bug o caratteristica? Scopriamo cosa sta succedendo.

All’interno del codice possiamo accedere al codice di versione da BuildConfig.VERSION_CODE o da PackageManager.packageInfo.versionCode:

Dopo aver eseguito il codice in Logcat vedremo esattamente quello che abbiamo osservato sopra:

Il motivo per cui questo accade è che negli strumenti di build di android gradle ci sono due task separati per generare il file BuildConfig e per elaborare AndroidManifest.

Se guardiamo dentro GenerateBuildConfig vedremo che la proprietà VERSION_CODE è generata dal metodo getVersionCode():

E che getVersionCodesi riferisce al valore memorizzato in variantConfiguration:

A differenza della generazione di BuildConfig in ProcessApplicationManifest vediamo che il codice della versione è recuperato da apkData.

Se controlliamo variantConfiguration e apkData prima e dopo aver impostato l’override del codice versione:

Vedremo che il valore all’interno dell’output apkData è stato cambiato sebbene il valore originale in variantConfiguration resti lo stesso (come previsto):

Come detto in questo problema è fatto intenzionalmente per ragioni di performance.

Conclusione

Fate attenzione se usate setVersionCodeOverride perché potreste avere codici di versione diversi in BuildConfig e AndroidManifest.

Secondo la documentazione, inoltre, il modo raccomandato per controllare il codice di versione è quello di accedervi tramite PackageManager, non tramite BuildConfig:

Ancora meglio è avere una logica di versioning al di fuori di build.gradle e fornirla tramite un parametro gradle dal tuo CI.

Inoltre è una scelta saggia non fare molto affidamento nel tuo codebase su BuildConfig.VERSION_CODE. Per i casi di migrazione è meglio introdurre il proprio versionamento locale (come si fa con i database SQL).

Felice codifica!