Creare più APK

Attenzione:da agosto 2021, tutti i nuovi le app devono essere pubblicate come app bundle. Se pubblichi la tua app su Google Play, creare e caricare un Android App Bundle. Quando esegui questa operazione, Google Play genera e pubblica automaticamente APK ottimizzati configurazione del dispositivo di ciascun utente, pertanto scarica solo il codice e le risorse di cui hanno bisogno per eseguire la tua app. La pubblicazione di più APK è utile se in un negozio che non supporta il formato AAB. In questo caso, devi creare, firmare e gestire ogni APK personalmente.

Sebbene sia meglio creare un singolo APK per supportare tutti i dispositivi di destinazione quando possibile, ciò potrebbe generare un APK di grandi dimensioni a causa dei file supporta più densità schermo o Binario applicazione interfacce (ABI). Un modo per ridurre le dimensioni dell'APK è creare più APK che contenere file per densità dello schermo o ABI specifiche.

Gradle può creare APK separati contenenti solo codice e risorse specifici a ogni densità o ABI. Questa pagina descrive come configurare la build in generare più APK. Se devi creare versioni diverse dell'app che non si basano sulla densità dello schermo o sull'ABI, usa invece le varianti della build.

Configurare la build per più APK

Per configurare la build per più APK, aggiungi un splits a livello di modulo build.gradle file. All'interno del splits blocco, fornisci un blocco density che specifica come vuoi che venga generato da Gradle APK a densità o un blocco abi che specifica come vuoi che Gradle per generare APK per ABI. Puoi fornire blocchi di densità e ABI e Il sistema di compilazione crea un APK per ogni combinazione di densità e ABI.

Configura più APK per le densità dello schermo

Per creare APK separati per densità schermo diverse, aggiungi un density blocco all'interno di Blocco splits. Nel tuo blocco density, fornisci un elenco di densità e dimensioni dello schermo compatibili. Utilizza solo l'elenco di schermi di dimensioni specifiche <compatible-screens> nel file manifest di ogni APK.

Le seguenti opzioni Gradle DSL vengono utilizzate per configurare più APK per densità schermo:

enable per Groovy, isEnable per script Kotlin
Se imposti questo elemento su true, Gradle genera più APK. in base alle densità dello schermo che definisci. Il valore predefinito è false.
exclude
Specifica un elenco separato da virgole di densità che non vuoi che Gradle per cui generare APK separati. Usa exclude se vuoi generare APK per la maggior parte delle densità, ma devi escluderne alcune di densità non supportate dalla tua app.
reset()

Cancella l'elenco predefinito di densità dello schermo. Da utilizzare solo se combinato con include elemento per specificare le densità che vuoi aggiungere.

Lo snippet seguente imposta l'elenco di densità su ldpi e xxhdpi chiamando il numero reset() per cancellare l'elenco, quindi utilizzare include:

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 separato da virgole di densità che vuoi generare da Gradle APK per Usalo solo in combinazione con reset() per specificare un valore l'elenco esatto di densità.
compatibleScreens

Specifica un elenco separato da virgole di dimensioni dello schermo compatibili. In questo modo un elemento <compatible-screens> nel file manifest per ogni APK.

Questa impostazione offre un modo pratico per gestire entrambi gli schermi densità e dimensioni dello schermo nella stessa sezione build.gradle. Tuttavia, utilizzando <compatible-screens> può limitare i tipi di dispositivo con cui funziona la tua app. Per scoprire metodi alternativi per supportare dimensioni dello schermo, consulta Panoramica della compatibilità dello schermo.

Poiché ogni APK basato sulla densità dello schermo include un'immagine <compatible-screens> tag con restrizioni specifiche sui tipi di schermata supportati dall'APK, anche se ne pubblichi diversi APK: alcuni nuovi dispositivi non corrispondono ai filtri APK multipli. Di conseguenza, Gradle genera sempre un APK universale aggiuntivo contenente asset per tutte le densità dello schermo e non include un Tag <compatible-screens>. Pubblica questo universale insieme agli APK a densità come un fallback per che non corrispondono agli APK con un Tag <compatible-screens>.

L'esempio seguente genera un APK separato per ogni schermo ad alta densità tranne ldpi, xxhdpi e xxxhdpi. A questo scopo, usa exclude per la rimozione. quelle tre densità dall'elenco predefinito di tutte le densità.

Alla moda

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 maggiori dettagli sulla personalizzazione di diverse build della tua app per tipi di schermo e dispositivi specifici; consulta Dichiarazione soggetta a limitazioni il supporto dello schermo.

Configurare più APK per le ABI

Per creare APK separati per ABI diverse, aggiungi un blocco abi all'interno Blocco splits. Nel blocco abi, fornisci un elenco di ABI desiderate.

Le seguenti opzioni Gradle DSL vengono utilizzate per configurare più APK per ABI:

enable per lo script Groovy o isEnable per lo script Kotlin
Se imposti questo elemento su true, Gradle genera più APK basati sulle ABI che hai definito. Il valore predefinito è false.
exclude
Specifica un elenco separato da virgole di ABI che non vuoi che Gradle generare APK separati. Usa exclude se vuoi generare APK per la maggior parte delle ABI, ma devono escludere alcune ABI non incluse nell'app assistenza in tempo reale.
reset()

Cancella l'elenco predefinito di ABI. Da utilizzare solo se combinato con include per specificare le ABI da aggiungere.

Lo snippet seguente imposta l'elenco di ABI solo su x86 e x86_64 chiamando il numero reset() per cancellare la lista e quindi utilizzando include:

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 . Utilizzalo solo in combinazione con reset() per specificare un valore l'elenco delle ABI.
universalApk per Groovy o isUniversalApk per Alfabeto Kotlin

Se true, Gradle genera un APK universale oltre a APK per ABI. Un APK universale contiene codice e risorse per tutte le ABI in un un singolo APK. Il valore predefinito è false.

Tieni presente che questa opzione è disponibile disponibili nel blocco splits.abi. Durante la creazione di 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, usa reset() per iniziare con un elenco vuoto di ABI, seguito da include con un elenco di ABI a cui viene assegnato 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, vedi Supportato ABI.

Progetti senza codice nativo/C++

Per i progetti privi di codice nativo/C++, il riquadro Varianti build presenta due colonne: Module e Active Build Variante, come mostrata nella Figura 1.

Riquadro varianti build
Figura 1. Il riquadro Varianti build ha due colonne per i progetti senza e il codice nativo/C++.

Il valore Variante build attiva per il parametro 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 build attiva per un modulo e scegli la variante desiderata dal campo elenco.

Progetti con codice nativo/C++

Per i progetti con codice nativo/C++, il riquadro Varianti build presenta tre colonne: Module, Build attiva Variante e ABI attiva, come mostrato nella Figura 2.

Figura 2. Il riquadro Varianti build aggiunge la colonna ABI attiva per con codice nativo/C++.

Il valore della variante della build attiva per il modulo determina la variante di build di cui è stato eseguito il deployment ed è visibile nell'editor. Per i moduli nativi, il valore ABI attiva determina l'ABI che l'editor ma non influisce su ciò che viene implementato.

Per modificare il tipo di build o l'ABI:

  1. Fai clic sulla cella per la variante della build attiva o ABI attiva.
  2. Scegli dall'elenco la variante o l'ABI che ti interessa . Viene eseguita automaticamente una nuova sincronizzazione.

Se modifichi una delle colonne per un'app o un modulo libreria, la modifica viene applicata a tutte le app righe dipendenti.

Configura il controllo delle versioni

Per impostazione predefinita, quando Gradle genera più APK, ogni APK ha lo stesso le informazioni sulla versione, come specificato nel build.gradle o build.gradle.kts. 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 prima del caricamento sul Play Store.

Puoi configurare il file build.gradle a livello di modulo sostituisci versionCode per ogni APK. Creando un mapping che assegna un valore numerico univoco per ogni ABI e densità che configuri per più APK, puoi sostituire il codice di versione di output con un valore combini il codice di versione definito all'interno di defaultConfig oppure Blocco productFlavors con il valore numerico assegnato al o ABI.

Nell'esempio seguente, l'APK dell'ABI x86 ottiene un versionCode del 2004 e l'ABI x86_64 ottiene un versionCode di 3004.

L'assegnazione di codici di versione a grandi incrementi, ad esempio 1000, consente di assegnare in un secondo momento codici di versione univoci se devi aggiornare l'app. Per ad esempio, se defaultConfig.versionCode esegue l'iterazione a 5 in una successivo, Gradle assegna un versionCode del 2005 a dall'APK x86 e da 3005 all'APK x86_64.

Suggerimento: se la tua build include un APK universale, assegnagli un versionCode inferiore a quella di qualsiasi altro tuo APK. Perché il Google Play Store installa la versione della tua app che è compatibile con il dispositivo di destinazione e dispone della versionCode, assegnando un valore versionCode inferiore al universale garantisce che il Google Play Store provi a installare uno dei tuoi prima di ricorrere all'APK universale. Il seguente codice campione gestisce il tutto non eseguendo l'override di un file APK universale il valore predefinito di versionCode.

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]

// 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 codice delle versioni alternative, vedi Assegnazione dei codici di versione.

Creare più APK

Dopo aver configurato il build.gradle a livello di modulo build.gradle.kts per creare più APK, fai clic Crea > Crea APK per creare tutti gli APK per le app modulo selezionato nel riquadro Progetto. Gradle crea gli APK per ogni densità o ABI in build/outputs/apk/ del progetto .

Gradle crea un APK per ogni densità o ABI per cui configuri più APK. Se attivi più APK sia per le densità sia per le ABI, Gradle crea un APK per ogni combinazione di densità e ABI.

Ad esempio, Lo snippet build.gradle consente di creare più APK per mdpi e Densità hdpi, nonché x86 e x86_64 ABI:

Alla moda

...
  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 quattro APK:

  • app-hdpiX86-release.apk: contiene codice e risorse per Densità hdpi e x86 ABI.
  • app-hdpiX86_64-release.apk: contiene codice e risorse per Densità hdpi e x86_64 ABI.
  • app-mdpiX86-release.apk: contiene codice e risorse per Densità mdpi e x86 ABI.
  • app-mdpiX86_64-release.apk: contiene codice e risorse per Densità mdpi e x86_64 ABI.

Durante la creazione di diversi APK in base alla densità dello schermo, Gradle genera 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 tutti ABI 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 del file APK

Quando crea diversi APK, Gradle genera nomi file APK utilizzando quanto segue: schema:

modulename-screendensityABI-buildvariant.apk

I componenti dello schema sono:

modulename
Specifica il nome del modulo che si sta creando.
screendensity
Se sono attivi più APK per la densità dello schermo, viene specificata la schermata densità dell'APK, ad esempio mdpi.
ABI

Se sono abilitati più APK per ABI, specifica l'ABI per l'APK, ad esempio come x86.

Se sono attivi più APK sia per la densità schermo sia per ABI, Gradle concatena il nome della densità con il nome dell'ABI, ad esempio mdpiX86. Se il criterio universalApk è abilitato per ogni ABI APK, Gradle utilizza universal come parte ABI dell'APK universale nome file.

buildvariant
Specifica la variante di build che si sta creando, ad esempio debug.

Ad esempio, durante la creazione di un APK con densità schermo mdpi per di debug di myApp, il nome file dell'APK è myApp-mdpi-debug.apk. La release di myApp configurata per creare più APK per La densità schermo di mdpi e l'ABI x86 hanno un nome file APK di myApp-mdpiX86-release.apk.