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 caso, Google Play genera e pubblica automaticamente APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che gli utenti scarichino solo il codice e le risorse necessarie per eseguire la tua app. La pubblicazione di più APK è utile se pubblichi in uno store che non supporta il formato AAB. In questo caso, devi creare, firmare e gestire personalmente ogni APK.
Sebbene sia meglio creare un singolo APK per supportare tutti i dispositivi di destinazione, se possibile, ciò potrebbe generare un APK molto grande a causa dei file che supportano più densità di schermo o interfaccia utente binaria delle applicazioni (ABI). Un modo per ridurre le dimensioni dell'APK consiste nel creare più APK contenenti file per ABI o densità dello schermo specifiche.
Gradle può creare APK separati contenenti solo codice e risorse specifici di ogni densità o ABI. In questa pagina viene descritto come configurare la build per generare più APK. Se devi creare versioni diverse della tua app non basate sulla densità dello schermo o sull'ABI, utilizza invece le varianti della 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 density
che specifichi in che modo Gradle generi APK per densità o un blocco abi
che specifichi la modalità di generazione degli APK per ABI da parte di Gradle. Puoi fornire blocchi sia per densità sia per ABI; il sistema di build crea un APK per ogni combinazione di densità e ABI.
Configurare più APK per le densità dello schermo
Per creare APK separati per diverse densità dello schermo, aggiungi un
blocco density
all'interno del blocco
splits
. Nel blocco density
, fornisci un
elenco di densità e dimensioni dello schermo compatibili. Utilizza l'elenco di dimensioni dello schermo compatibili solo se ti servono elementi
<compatible-screens>
specifici nel file manifest di ogni APK.
Le seguenti opzioni DSL Gradle vengono utilizzate per configurare più APK per le densità dello schermo:
-
enable
per Groovy,isEnable
per lo script Kotlin -
Se imposti questo elemento su
true
, Gradle genera più APK in base alle densità dello schermo definite. Il valore predefinito èfalse
. -
exclude
-
Specifica un elenco di densità separate da virgole per cui non vuoi che Gradle generi APK separati. Utilizza
exclude
se vuoi generare APK per la maggior parte delle densità, ma devi escludere alcune densità non supportate dalla tua app. -
reset()
-
Cancella l'elenco predefinito di densità dello schermo. Utilizzalo solo se combinato con l'elemento
include
per specificare le densità che vuoi aggiungere.Lo snippet seguente imposta l'elenco di densità solo su
ldpi
exxhdpi
chiamandoreset()
per cancellare l'elenco, quindi utilizzandoinclude
:reset() // Clears the default list from all densities // to no densities. include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs // for.
-
include
-
Specifica un elenco di densità separate da virgole per cui vuoi che Gradle generi gli APK. Utilizzala solo in combinazione con
reset()
per specificare un elenco esatto di densità. -
compatibleScreens
-
Specifica un elenco separato da virgole di dimensioni dello schermo compatibili. Questa operazione inserisce un nodo
<compatible-screens>
corrispondente nel file manifest per ogni APK.Questa impostazione consente di gestire facilmente sia le densità sia le dimensioni dello schermo nella stessa sezione
build.gradle
. Tuttavia, l'utilizzo di<compatible-screens>
può limitare i tipi di dispositivi su cui funziona la tua app. Per conoscere modi alternativi per supportare schermi di diverse dimensioni, consulta la panoramica sulla compatibilità dello schermo.
Poiché ogni APK basato sulla densità dello schermo include un tag <compatible-screens>
con limitazioni specifiche sui tipi di schermata supportati dall'APK, anche se pubblichi diversi APK, alcuni nuovi dispositivi non corrispondono ai diversi filtri APK. Di conseguenza, Gradle genera sempre un APK universale aggiuntivo che contiene asset per tutte le densità dello schermo e non include un tag <compatible-screens>
. Pubblica questo
APK universale insieme agli APK in base alla densità per fornire un video di riserva per i
dispositivi che non corrispondono agli APK con un
tag <compatible-screens>
.
L'esempio seguente genera un APK separato per ogni
compattezza
dello schermo, ad eccezione di ldpi
, xxhdpi
e
xxxhdpi
. A questo scopo, utilizza exclude
per rimuovere
queste tre densità dall'elenco predefinito di tutte le densità.
Trendy
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. enable true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude "ldpi", "xxhdpi", "xxxhdpi" // Specifies a list of compatible screen size settings for the manifest. compatibleScreens 'small', 'normal', 'large', 'xlarge' } } }
Kotlin
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. isEnable = true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude("ldpi", "xxhdpi", "xxxhdpi") // Specifies a list of compatible screen size settings for the manifest. compatibleScreens("small", "normal", "large", "xlarge") } } }
Per un elenco dei nomi delle densità e delle dimensioni dello schermo, consulta la sezione Supportare dimensioni dello schermo diverse. Per maggiori dettagli su come personalizzare diverse varianti di build della tua app per tipi di schermo e dispositivi specifici, consulta la pagina Dichiarare il supporto per schermo limitato.
Configurare più APK per le ABI
Per creare APK separati per ABI diverse, aggiungi un blocco abi
all'interno del blocco splits
. Nel blocco abi
, fornisci un elenco delle ABI desiderate.
Per configurare più APK per ABI vengono utilizzate le seguenti opzioni DSL Gradle:
-
enable
per lo script Groovy oisEnable
per lo script Kotlin - Se imposti questo elemento su
true
, Gradle genera più APK in base alle ABI definite. Il valore predefinito èfalse
. -
exclude
-
Specifica un elenco separato da virgole di ABI per le quali non vuoi che Gradle generi APK separati. Utilizza
exclude
se 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. Utilizzalo solo se combinato con l'elemento
include
per specificare le ABI che vuoi aggiungere.Lo snippet seguente imposta l'elenco di ABI solo su
x86
ex86_64
chiamandoreset()
per cancellare l'elenco, quindi 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 le quali vuoi che Gradle generi gli APK. Utilizzala solo in combinazione con
reset()
per specificare un elenco esatto di ABI. -
universalApk
per Groovy oisUniversalApk
per 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
.Tieni presente che questa opzione è disponibile solo nel blocco
splits.abi
. Quando crei più APK in base alla densità dello schermo, Gradle genera sempre un APK universale che contiene codice e risorse per tutte le densità dello schermo.
L'esempio seguente genera un APK separato per ogni ABI: x86
e x86_64
. Per farlo, utilizza reset()
per iniziare con un elenco vuoto di ABI, seguito da include
con un
elenco di ABI a cui ciascuna riceve un APK.
Trendy
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 la pagina ABI supportate.
Progetti senza codice nativo/C++
Per i progetti senza codice nativo/C++, il riquadro Genera varianti ha due colonne: Modulo e Variante build attiva, come mostrato nella Figura 1.
Figura 1. Il riquadro Crea varianti ha due colonne per i progetti senza codice nativo/C++.
Il valore Variante build attiva per il modulo determina la variante build di cui viene eseguito il deployment e che è visibile nell'editor. Per passare da una variante all'altra, fai clic sulla cella Variante build attiva per un modulo e scegli la variante che ti interessa dal campo dell'elenco.
Progetti con codice nativo/C++
Per i progetti con codice nativo/C++, il riquadro Genera varianti ha tre colonne: Modulo, Variante build attiva e ABI attiva, come mostrato nella Figura 2.
Figura 2. Il riquadro Crea varianti aggiunge la colonna ABI attiva per i progetti con codice nativo/C++.
Il valore Variante build attiva per il modulo determina la variante di build di cui viene eseguito il deployment ed è visibile nell'editor. Per i moduli nativi, il valore ABI attiva determina l'ABI utilizzata dall'editor, ma non influisce sugli elementi di cui viene eseguito il deployment.
Per modificare il tipo di build o ABI:
- Fai clic sulla cella della colonna Variante build attiva o ABI attiva.
- Scegli la variante o l'ABI desiderata nel campo dell'elenco. Viene eseguita automaticamente una nuova sincronizzazione.
La modifica di una colonna per un modulo dell'app o della libreria applica la modifica a tutte le righe dipendenti.
Configura il controllo delle versioni
Per impostazione predefinita, quando Gradle genera più APK, ogni APK 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 tutte le stesse informazioni sulla versione, devi assicurarti che ogni APK abbia un elemento
versionCode
univoco prima di caricarlo sul Play Store.
Puoi configurare il file build.gradle
a livello di modulo in modo da sostituire il valore versionCode
per ogni APK. Creando una mappatura che assegna un valore numerico univoco a ogni ABI e densità per cui configuri più APK, puoi sostituire il codice di versione di output con un valore che combina il codice di versione definito nel blocco defaultConfig
o productFlavors
con il valore numerico assegnato alla densità o all'ABI.
Nell'esempio seguente, l'APK dell'ABI x86
riceve un versionCode
del 2004 e l'APK dell'ABI x86_64
riceve un valore versionCode
di 3004.
L'assegnazione di codici di versione con incrementi ampi, ad esempio 1000, ti consente di assegnare in un secondo momento codici di versione univoci se devi aggiornare l'app. Ad esempio, se defaultConfig.versionCode
esegue l'iterazione a 5 in un aggiornamento successivo, Gradle assegna versionCode
2005 all'APK x86
e 3005 all'APK x86_64
.
Suggerimento: se la build include un APK universale, assegnagli un
versionCode
inferiore a quello degli altri APK.
Poiché Google Play Store installa la versione della tua app che è compatibile con il dispositivo di destinazione e ha il valore versionCode
più elevato, l'assegnazione di un valore versionCode
inferiore all'APK universale garantisce che il Google Play Store provi a installare uno dei tuoi APK prima di ricorrere all'APK universale. Il seguente codice campione
gestisce questo problema non sostituendo il valore predefinito versionCode
di un APK universale.
Trendy
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] // For per-density APKs, create a similar map: // ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 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) // For per-density APKs, create a similar map: // val densityCodes = mapOf("mdpi" to 1, "hdpi" to 2, "xhdpi" 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, consulta Assegnare i codici di versione.
Crea più APK
Dopo aver configurato il file build.gradle
o build.gradle.kts
a livello di modulo per creare più APK, fai clic su Crea > APK build per creare tutti gli APK per il modulo attualmente selezionato nel riquadro Progetto. Gradle crea gli APK per ogni densità o ABI nella directory build/outputs/apk/
del progetto.
Gradle crea un APK per ogni densità o ABI per cui configuri più APK. Se attivi più APK per densità e ABI, Gradle crea un APK per ogni combinazione di densità e ABI.
Ad esempio, il seguente snippet build.gradle
consente di creare più APK per le densità mdpi
e hdpi
, nonché per le ABI x86
e x86_64
:
Trendy
... splits { density { enable true reset() include "mdpi", "hdpi" } abi { enable true reset() include "x86", "x86_64" } }
Kotlin
... splits { density { isEnable = true reset() include("mdpi", "hdpi") } abi { isEnable = true reset() include("x86", "x86_64") } }
L'output della configurazione di esempio include i seguenti 4 APK:
app-hdpiX86-release.apk
: contiene codice e risorse per la densità dihdpi
e l'ABI dix86
.app-hdpiX86_64-release.apk
: contiene codice e risorse per la densità dihdpi
e l'ABI dix86_64
.app-mdpiX86-release.apk
: contiene codice e risorse per la densità dimdpi
e l'ABI dix86
.app-mdpiX86_64-release.apk
: contiene codice e risorse per la densità dimdpi
e l'ABI dix86_64
.
Quando crei più APK in base alla densità dello schermo, Gradle genera sempre un APK universale che include codice e risorse per tutte le densità, oltre agli APK per densità.
Quando crei più APK basati su
ABI, Gradle genera solo un 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
nel file build.gradle.kts
(per lo script Kotlin).
Formato del nome del file APK
Quando crei più APK, Gradle genera i nomi file APK utilizzando il seguente schema:
modulename-screendensityABI-buildvariant.apk
I componenti dello schema sono:
-
modulename
- Specifica il nome del modulo in fase di creazione.
-
screendensity
-
Se sono attivati più APK per la densità dello schermo, viene specificata la densità dello schermo per l'APK, ad esempio
mdpi
. -
ABI
-
Se sono attivati più APK per ABI, specifica l'ABI per l'APK, ad esempio
x86
.Se sono abilitati più APK sia per la densità dello schermo sia per l'ABI, Gradle concatena il nome della densità con il nome dell'ABI, ad esempio
mdpiX86
. SeuniversalApk
è abilitato per gli APK per-ABI, Gradle utilizzauniversal
come parte ABI del nome file APK universale. -
buildvariant
-
Specifica la variante di build in fase di creazione, ad esempio
debug
.
Ad esempio, durante la creazione di un APK di densità dello schermo mdpi
per la versione di debug di myApp, il nome file dell'APK è myApp-mdpi-debug.apk
. La versione di release di myApp configurata per creare più APK per la densità dello schermo mdpi
e per l'ABI x86
ha un nome file APK myApp-mdpiX86-release.apk
.