Sebbene sia meglio creare un singolo APK per supportare tutti i dispositivi di destinazione, se possibile, ciò potrebbe comportare un APK di dimensioni molto grandi a causa dei file che supportano più Application Binary Interface (ABI). Un modo per ridurre le dimensioni dell'APK è creare più APK contenenti 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 sono basate su ABI, utilizza invece le varianti di compilazione.
Configura 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 in che modo vuoi che Gradle generi gli APK per ABI.
Configura 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 scelte.
Le seguenti opzioni DSL di Gradle vengono utilizzate per configurare più APK per ABI:
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 escluderne alcune non supportate dalla tua app. reset()Cancella l'elenco predefinito di ABI. Utilizzalo solo in combinazione con l'elemento
includeper specificare le ABI che vuoi aggiungere.Lo snippet seguente 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.includeSpecifica un elenco separato da virgole di ABI per cui vuoi che Gradle generi APK. Da utilizzare solo in combinazione con
reset()per specificare un elenco esatto di ABI.universalApkper Groovy oisUniversalApkper lo script KotlinSe
true, Gradle genera un APK universale oltre agli APK per ABI. Un APK universale contiene codice e risorse per tutte le ABI in un singolo APK. Il valore predefinito èfalse.
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, ognuna delle quali riceve un APK.
Alla moda
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 compilazione ha due colonne: Modulo e Variante di compilazione attiva, come mostrato nella figura 1.
Il valore Variante di compilazione attiva per il modulo determina la variante di compilazione che viene distribuita e visualizzata nell'editor. Per passare da una variante all'altra, fai clic sulla cella Variante di compilazione attiva di un modulo e seleziona la variante scelta dal campo dell'elenco.
Progetti con codice nativo/C++
Per i progetti con codice nativo/C++, il riquadro Varianti di compilazione ha tre colonne: Modulo, Variante di compilazione attiva e ABI attiva, come mostrato nella figura 2.
Il valore Variante di compilazione attiva per il modulo determina la variante di compilazione di cui viene eseguito il deployment ed è visibile nell'editor. Per i moduli nativi, il valore ABI attivo determina l'ABI utilizzato dall'editor, ma non influisce su ciò di cui viene eseguito il deployment.
Per modificare il tipo di build o l'ABI:
- Fai clic sulla cella della colonna Variante di compilazione attiva o ABI attiva.
- Seleziona la variante o l'ABI che hai scelto dal campo dell'elenco. Viene eseguita automaticamente una nuova sincronizzazione.
La modifica di una delle colonne per un modulo di app o 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 con le stesse informazioni sulla versione, devi assicurarti che ogni APK abbia un versionCode univoco prima di caricarli sul Play Store.
Puoi configurare il file build.gradle a livello di modulo per eseguire l'override di
versionCode per ogni APK. Creando una mappatura che assegna un valore numerico univoco per ogni ABI per cui configuri più APK, puoi eseguire l'override del 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 pari a 2004
e l'ABI x86_64 riceve un versionCode pari a 3004.
L'assegnazione di codici versione con incrementi elevati, ad esempio 1000, ti consente di assegnare in un secondo momento codici versione univoci se devi aggiornare l'app. Ad esempio, se defaultConfig.versionCode viene ripetuto fino a 5 in un aggiornamento successivo, Gradle assegna un versionCode di 2005 all'APK x86 e 3005 all'APK x86_64.
Alla moda
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, consulta Assegnazione dei 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 Build > Build APK (Crea > Crea APK) per creare tutti gli APK per il modulo attualmente selezionato nel riquadro Project (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:
Alla moda
... 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 4 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 basati su ABI, Gradle genera un APK che include codice e risorse per tutte le ABI solo se specifichi universalApk true nel blocco splits.abi nel file build.gradle (per Groovy) o isUniversalApk = true nel blocco splits.abi nel file build.gradle.kts (per lo script Kotlin).
Formato del nome file APK
Quando crei più APK, Gradle genera i nomi file degli APK utilizzando il seguente schema:
modulename-ABI-buildvariant.apk
I componenti dello schema sono:
modulename- Specifica il nome del modulo in fase di creazione.
ABI- Se sono attivati più APK per ABI, specifica l'ABI per l'APK, ad esempio
x86. buildvariant- Specifica la variante di build in fase di compilazione, ad esempio
debug.