Attenzione:da agosto 2021, tutte le nuove app devono essere pubblicate come App Bundle. Se pubblichi la tua app su Google Play, crea e carica un Android App Bundle. In questo modo, Google Play genera e pubblica automaticamente APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che scarichi solo il codice e le risorse necessari per eseguire l'app. La pubblicazione di più APK è utile se pubblichi su uno store che non supporta il formato AAB. In questo caso, devi creare, firmare e gestire ogni APK autonomamente.
Anche se è preferibile creare un singolo APK per supportare tutti i dispositivi di destinazione ogni volta che è possibile, ciò potrebbe comportare un APK molto grande a causa dei file che supportano più Application Binary Interfaces (ABI). Un modo per ridurre le dimensioni dell'APK è creare più APK che contengano file per ABI specifiche.
Gradle può creare APK separati che contengono solo codice e risorse specifici per ogni ABI. Questa pagina descrive come configurare la build per generare più APK. Se devi creare versioni diverse della tua app che non si basano sull'ABI, utilizza invece le varianti di build.
Configurare la build per più APK
Per configurare la build per più APK, aggiungi un
blocco
splits al file
build.gradle a livello di modulo. All'interno del blocco
splits, fornisci un blocco
abi che specifica come vuoi che Gradle
generi gli APK per ABI.
Configurare più APK per gli ABI
Per creare APK separati per ABI diversi, aggiungi un blocco abi
all'interno del blocco
splits. Nel blocco abi, fornisci un elenco di
ABI desiderate.
Per configurare più APK per ABI vengono utilizzate le seguenti opzioni DSL di Gradle:
-
enableper Groovy oisEnableper lo script Kotlin - Se imposti questo elemento su
true, Gradle genera più APK in base alle ABI che definisci. Il valore predefinito èfalse. -
exclude -
Specifica un elenco separato da virgole di ABI per cui non vuoi che Gradle
generi APK separati. Utilizza
excludese vuoi generare APK per la maggior parte delle ABI, ma devi escludere alcune ABI non supportate dalla tua app. -
reset() -
Cancella l'elenco predefinito di ABI. Utilizza solo in combinazione con l'elemento
includeper specificare le ABI che vuoi aggiungere.Il seguente snippet imposta l'elenco delle ABI solo su
x86ex86_64chiamandoreset()per cancellare l'elenco e poi utilizzandoinclude:reset() // Clears the default list from all ABIs to no ABIs. include "x86", "x86_64" // Specifies the two ABIs we want to generate APKs for.
-
include -
Specifica un elenco separato da virgole di ABI per cui vuoi che Gradle generi APK. Utilizzare solo in combinazione con
reset()per specificare un elenco esatto di ABI. -
universalApkper Groovy oisUniversalApkper lo script Kotlin -
Se
true, Gradle genera un APK universale oltre agli APK per ABI. Un APK universale contiene codice e risorse per tutte le ABI in un unico APK. Il valore predefinito èfalse.
L'esempio seguente genera un APK separato per ogni ABI: x86
e x86_64. A questo scopo, utilizza reset()
per iniziare con un elenco vuoto di ABI, seguito da include con un
elenco di ABI per ognuna delle quali viene creato un APK.
Groovy
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. enable true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include "x86", "x86_64" // Specifies that you don't want to also generate a universal APK that includes all ABIs. universalApk false } } }
Kotlin
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. isEnable = true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include("x86", "x86_64") // Specifies that you don't want to also generate a universal APK that includes all ABIs. isUniversalApk = false } } }
Per un elenco delle ABI supportate, consulta ABI supportate.
Progetti senza codice nativo/C++
Per i progetti senza codice nativo/C++, il riquadro Varianti di build ha due colonne: Modulo e Variante di build attiva, come mostrato nella figura 1.

Figura 1. Il pannello Crea varianti ha due colonne per i progetti senza codice nativo/C++.
Il valore Variante di build attiva per il modulo determina la variante di build di cui viene eseguito il deployment e che è visibile nell'editor. Per passare da una variante all'altra, fai clic sulla cella Variante di build attiva di un modulo e scegli la variante che preferisci dal campo dell'elenco.
Progetti con codice nativo/C++
Per i progetti con codice nativo/C++, il riquadro Varianti di build ha tre colonne: Modulo, Variante di build attiva e ABI attiva, come mostrato nella figura 2.
Figura 2. Il riquadro Varianti di build aggiunge la colonna ABI attiva per
i progetti con codice nativo/C++.
Il valore Variante di build attiva per il modulo determina la variante di build di cui viene eseguito il deployment e che è visibile nell'editor. Per i moduli nativi, il valore ABI attivo determina l'ABI utilizzato dall'editor, ma non influisce su ciò che viene implementato.
Per modificare il tipo di build o l'ABI:
- Fai clic sulla cella della colonna Variante build attiva o ABI attiva.
- Scegli la variante o l'ABI che preferisci dal campo dell'elenco. Viene eseguita automaticamente una nuova sincronizzazione.
La modifica di una delle due colonne per un modulo dell'app o della libreria viene applicata a tutte le righe dipendenti.
Configurare il controllo delle versioni
Per impostazione predefinita, quando Gradle genera più APK, ognuno ha le stesse
informazioni sulla versione, come specificato nel file
build.gradle o build.gradle.kts a livello di modulo. Poiché
il Google Play Store non consente più APK per la stessa app che hanno tutti
le stesse informazioni sulla versione, devi assicurarti che ogni APK abbia un
versionCode univoco prima di caricarlo sul Play Store.
Puoi configurare il file build.gradle a livello di modulo per
ignorare versionCode per ogni APK. Se crei una mappatura
che assegna un valore numerico univoco a ogni ABI per cui configuri
più APK, puoi sostituire il codice di versione di output con un valore che
combina il codice di versione definito all'interno del blocco defaultConfig o
productFlavors con il valore numerico assegnato all'ABI.
Nell'esempio seguente, l'APK per l'ABI x86
riceve un versionCode di 2004 e l'ABI x86_64
riceve un versionCode di 3004.
L'assegnazione di codici di versione con incrementi elevati, ad esempio 1000, ti consente
di assegnare in un secondo momento codici di versione univoci se devi aggiornare la tua app. Ad esempio, se defaultConfig.versionCode viene incrementato a 5 in un
aggiornamento successivo, Gradle assegna un valore versionCode di 2005 all'APK x86 e 3005 all'APK x86_64.
Suggerimento:se la build include un APK universale, assegnagli un
versionCode inferiore a quello di tutti gli altri APK.
Poiché Google Play Store installa la versione dell'app che è sia
compatibile con il dispositivo di destinazione sia con il versionCode più alto, assegnando un versionCode inferiore all'APK universale si garantisce che Google Play Store tenti di installare uno degli APK prima di ripiegare sull'APK universale. Il seguente codice campione
gestisce questo problema non eseguendo l'override del versionCode
predefinito di un APK universale.
Groovy
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // Map for the version code that gives each ABI a value. ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3] import com.android.build.OutputFile // For each APK output variant, override versionCode with a combination of // ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. android.applicationVariants.all { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.each { output -> // Stores the value of ext.abiCodes that is associated with the ABI for this variant. def baseAbiVersionCode = // Determines the ABI for this variant and returns the mapped value. project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiVersionCode != null) { // Assigns the new version code to versionCodeOverride, which changes the // version code for only the output APK, not for the variant itself. Skipping // this step causes Gradle to use the value of variant.versionCode for the APK. output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode } } }
Kotlin
android { ... defaultConfig { ... versionCode = 4 } splits { ... } } // Map for the version code that gives each ABI a value. val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3) import com.android.build.api.variant.FilterConfiguration.FilterType.* // For each APK output variant, override versionCode with a combination of // abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. androidComponents { onVariants { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == ABI }?.identifier // Stores the value of abiCodes that is associated with the ABI for this variant. val baseAbiCode = abiCodes[name] // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiCode != null) { // Assigns the new version code to output.versionCode, which changes the version code // for only the output APK, not for the variant itself. output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0)) } } } }
Per altri esempi di schemi di codici di versione alternativi, vedi Assegnazione di codici di versione.
Creare più APK
Dopo aver configurato il file build.gradle o build.gradle.kts a livello di modulo per creare più APK, fai clic su Build > Build APK per creare tutti gli APK per il modulo attualmente selezionato nel riquadro Progetto. Gradle crea gli APK
per ogni ABI nella directory build/outputs/apk/
del progetto.
Gradle crea un APK per ogni ABI per cui configuri più APK.
Ad esempio, il seguente snippet
build.gradle consente di creare più APK per
le ABI x86 e x86_64:
Groovy
... splits { abi { enable true reset() include "x86", "x86_64" } }
Kotlin
... splits { abi { isEnable = true reset() include("x86", "x86_64") } }
L'output della configurazione di esempio include i seguenti quattro APK:
app-X86-release.apk: Contiene codice e risorse per l'ABIx86.app-X86_64-release.apk: Contiene codice e risorse per l'ABIx86_64.
Quando crei più APK in base all'ABI, Gradle genera un solo APK che include codice e risorse per tutte le ABI se specifichi universalApk true nel blocco splits.abi del file build.gradle (per Groovy) o isUniversalApk = true nel blocco splits.abi del file build.gradle.kts (per Kotlin Script).
Formato del nome del file APK
Quando crei più APK, Gradle genera i nomi dei file APK utilizzando lo schema seguente:
modulename-ABI-buildvariant.apk
I componenti dello schema sono:
-
modulename - Specifica il nome del modulo in fase di creazione.
-
ABI -
Se sono abilitati più APK per ABI, specifica l'ABI per l'APK, ad esempio
x86. -
buildvariant -
Specifica la variante di build in fase di creazione, ad esempio
debug.