Achtung:Seit August 2021 müssen alle neuen Apps als App-Bundles veröffentlicht werden. Wenn Sie Ihre App bei Google Play veröffentlichen, erstellen und laden Sie ein Android App Bundle hoch. Google Play generiert und stellt dann automatisch optimierte APKs für die Gerätekonfiguration jedes Nutzers bereit. So müssen Nutzer nur den Code und die Ressourcen herunterladen, die sie zum Ausführen Ihrer App benötigen. Das Veröffentlichen mehrerer APKs ist nützlich, wenn Sie Ihre App in einem Store veröffentlichen, der das AAB-Format nicht unterstützt. In diesem Fall müssen Sie jedes APK selbst erstellen, signieren und verwalten.
Es ist zwar besser, nach Möglichkeit ein einzelnes APK zu erstellen, das alle Zielgeräte unterstützt. Das kann jedoch zu einem sehr großen APK führen, da Dateien mehrere Bildschirmdichten oder Application Binary Interfaces (ABIs) unterstützen. Eine Möglichkeit, die Größe Ihres APK zu reduzieren, besteht darin, mehrere APKs zu erstellen, die Dateien für bestimmte Bildschirmdichten oder ABIs enthalten.
Gradle kann separate APKs erstellen, die nur Code und Ressourcen enthalten, die für jede Dichte oder jedes ABI spezifisch sind. Auf dieser Seite wird beschrieben, wie Sie Ihren Build so konfigurieren, dass mehrere APKs generiert werden. Wenn Sie verschiedene Versionen Ihrer App erstellen möchten, die nicht auf Bildschirmdichte oder ABI basieren, verwenden Sie stattdessen Build-Varianten.
Build für mehrere APKs konfigurieren
Wenn Sie Ihren Build für mehrere APKs konfigurieren möchten, fügen Sie der Datei build.gradle
auf Modulebene den Block
splits
hinzu. Geben Sie innerhalb des splits
-Blocks einen density
-Block an, in dem angegeben ist, wie Gradle APKs pro Dichte generieren soll, oder einen abi
-Block, in dem angegeben ist, wie Gradle APKs pro ABI generieren soll. Sie können sowohl Dichte- als auch ABI-Blöcke angeben. Das Build-System erstellt dann ein APK für jede Kombination aus Dichte und ABI.
Mehrere APKs für Bildschirmdichten konfigurieren
Wenn Sie separate APKs für verschiedene Bildschirmdichten erstellen möchten, fügen Sie einen density
-Block in den splits
-Block ein. Geben Sie in Ihrem density
-Block eine Liste der gewünschten Bildschirmdichten und kompatiblen Bildschirmgrößen an. Verwenden Sie die Liste der kompatiblen Bildschirmgrößen nur, wenn Sie bestimmte
<compatible-screens>
-Elemente im Manifest jedes APKs benötigen.
Mit den folgenden Gradle-DSL-Optionen können Sie mehrere APKs für Bildschirmdichten konfigurieren:
-
enable
für Groovy-,isEnable
für Kotlin-Script -
Wenn Sie dieses Element auf
true
festlegen, generiert Gradle mehrere APKs basierend auf den von Ihnen definierten Bildschirmdichten. Der Standardwert istfalse
. -
exclude
-
Eine durch Kommas getrennte Liste von Dichten, für die Gradle keine separaten APKs generieren soll. Verwenden Sie
exclude
, wenn Sie APKs für die meisten Dichten generieren, aber einige Dichten ausschließen möchten, die von Ihrer App nicht unterstützt werden. -
reset()
-
Die Standardliste der Bildschirmdichten wird gelöscht. Verwenden Sie dieses Element nur in Kombination mit dem
include
-Element, um die Dichten anzugeben, die Sie hinzufügen möchten.Im folgenden Snippet wird die Liste der Dichten auf nur
ldpi
undxxhdpi
festgelegt. Dazu wirdreset()
aufgerufen, um die Liste zu löschen, und danninclude
verwendet:reset() // Clears the default list from all densities // to no densities. include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs // for.
-
include
-
Gibt eine durch Kommas getrennte Liste von Dichten an, für die Gradle APKs generieren soll. Verwenden Sie diese Option nur in Kombination mit
reset()
, um eine genaue Liste der Dichten anzugeben. -
compatibleScreens
-
Gibt eine durch Kommas getrennte Liste kompatibler Bildschirmgrößen an. Dadurch wird für jedes APK ein passender
<compatible-screens>
-Knoten in das Manifest eingefügt.Mit dieser Einstellung können Sie sowohl die Bildschirmdichte als auch die Bildschirmgröße im selben Bereich
build.gradle
verwalten. Die Verwendung von<compatible-screens>
kann jedoch die Gerätetypen einschränken, mit denen Ihre App funktioniert. Alternative Möglichkeiten zur Unterstützung verschiedener Bildschirmgrößen finden Sie in der Übersicht zur Bildschirmkompatibilität.
Da jedes APK, das auf der Bildschirmdichte basiert, ein <compatible-screens>
-Tag mit bestimmten Einschränkungen zu den Bildschirmtypen enthält, die das APK unterstützt, stimmen einige neue Geräte nicht mit Ihren Filtern für mehrere APKs überein – auch wenn Sie mehrere APKs veröffentlichen. Daher generiert Gradle immer ein zusätzliches universelles APK, das Assets für alle Bildschirmdichten enthält und kein <compatible-screens>
-Tag enthält. Veröffentlichen Sie dieses universelle APK zusammen mit Ihren APKs für die einzelnen Dichten, um einen Fallback für Geräte bereitzustellen, die nicht mit den APKs mit einem <compatible-screens>
-Tag übereinstimmen.
Im folgenden Beispiel wird für jede Bildschirmdichte mit Ausnahme von ldpi
, xxhdpi
und xxxhdpi
ein separates APK generiert. Dazu entfernen Sie diese drei Dichten mit exclude
aus der Standardliste aller Dichten.
Groovy
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") } } }
Weitere Informationen zum Anpassen verschiedener Buildvarianten Ihrer App an bestimmte Bildschirmtypen und Geräte finden Sie unter Unterstützung für eingeschränkte Bildschirme angeben.
Mehrere APKs für ABIs konfigurieren
Wenn Sie separate APKs für verschiedene ABIs erstellen möchten, fügen Sie einen abi
-Block in den splits
-Block ein. Geben Sie in Ihrem abi
-Block eine Liste der gewünschten ABIs an.
Mit den folgenden Gradle DSL-Optionen können Sie mehrere APKs pro ABI konfigurieren:
-
enable
für Groovy oderisEnable
für Kotlin-Script - Wenn Sie dieses Element auf
true
festlegen, generiert Gradle mehrere APKs basierend auf den von Ihnen definierten ABIs. Der Standardwert istfalse
. -
exclude
-
Eine durch Kommas getrennte Liste von ABIs, für die Gradle keine separaten APKs generieren soll. Verwenden Sie
exclude
, wenn Sie APKs für die meisten ABIs generieren, aber einige ABIs ausschließen möchten, die von Ihrer App nicht unterstützt werden. -
reset()
-
Die Standardliste der ABIs wird gelöscht. Verwenden Sie dieses Element nur in Kombination mit dem
include
-Element, um die ABIs anzugeben, die Sie hinzufügen möchten.Im folgenden Snippet wird die Liste der ABIs auf
x86
undx86_64
festgelegt. Dazu wirdreset()
aufgerufen, um die Liste zu löschen, und danninclude
verwendet: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
-
Gibt eine durch Kommas getrennte Liste von ABIs an, für die Gradle APKs generieren soll. Verwenden Sie diese Option nur in Kombination mit
reset()
, um eine genaue Liste von ABIs anzugeben. -
universalApk
für Groovy oderisUniversalApk
für Kotlin-Script -
Wenn
true
festgelegt ist, generiert Gradle zusätzlich zu den ABI-spezifischen APKs ein universelles APK. Ein universelles APK enthält Code und Ressourcen für alle ABIs in einem einzigen APK. Der Standardwert istfalse
.Diese Option ist nur im Block
splits.abi
verfügbar. Wenn Sie mehrere APKs basierend auf der Bildschirmdichte erstellen, generiert Gradle immer ein universelles APK, das Code und Ressourcen für alle Bildschirmdichten enthält.
Im folgenden Beispiel wird für jedes ABI ein separates APK generiert: x86
und x86_64
. Dazu verwenden Sie reset()
, um mit einer leeren Liste von ABIs zu beginnen, gefolgt von include
mit einer Liste von ABIs, die jeweils ein APK erhalten.
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 } } }
Eine Liste der unterstützten ABIs finden Sie unter Unterstützte ABIs.
Projekte ohne nativen/C++-Code
Bei Projekten ohne nativen/C++-Code enthält der Bereich Build-Varianten zwei Spalten: Modul und Aktive Build-Variante, wie in Abbildung 1 dargestellt.
Abbildung 1. Der Bereich Build-Varianten enthält zwei Spalten für Projekte ohne nativen/C++-Code.
Der Wert Active Build Variant (Aktive Build-Variante) für das Modul bestimmt die Build-Variante, die bereitgestellt und im Editor angezeigt wird. Wenn Sie zwischen Varianten wechseln möchten, klicken Sie auf die Zelle Aktive Build-Variante für ein Modul und wählen Sie die gewünschte Variante aus dem Listenfeld aus.
Projekte mit nativem/C++-Code
Bei Projekten mit nativem/C++-Code enthält der Bereich Build-Varianten drei Spalten: Modul, Aktive Build-Variante und Aktives ABI, wie in Abbildung 2 dargestellt.
Abbildung 2. Im Bereich Build-Varianten wird die Spalte Aktiver ABI für Projekte mit nativem/C++-Code hinzugefügt.
Der Wert Active Build Variant (Aktive Build-Variante) für das Modul bestimmt die Build-Variante, die bereitgestellt und im Editor angezeigt wird. Bei nativen Modulen bestimmt der Wert Active ABI das ABI, das der Editor verwendet. Er hat jedoch keine Auswirkungen auf die Bereitstellung.
So ändern Sie den Buildtyp oder ABI:
- Klicken Sie auf die Zelle für die Spalte Active Build Variant (Aktive Build-Variante) oder Active ABI (Aktive ABI).
- Wählen Sie die gewünschte Variante oder ABI aus dem Listenfeld aus. Es wird automatisch eine neue Synchronisierung ausgeführt.
Wenn Sie eine der Spalten für ein App- oder Bibliotheksmodul ändern, wird die Änderung auf alle abhängigen Zeilen angewendet.
Versionierung konfigurieren
Wenn Gradle mehrere APKs generiert, haben diese standardmäßig dieselben Versionsinformationen, wie in der build.gradle
- oder build.gradle.kts
-Datei auf Modulebene angegeben. Da im Google Play Store keine mehrere APKs für dieselbe App mit denselben Versionsinformationen zulässig sind, muss jedes APK vor dem Hochladen in den Play Store eine eindeutige
versionCode
haben.
Sie können die Datei build.gradle
auf Modulebene so konfigurieren, dass die versionCode
für jedes APK überschrieben wird. Wenn Sie eine Zuordnung erstellen, die jedem ABI und jeder Dichte, für die Sie mehrere APKs konfigurieren, einen eindeutigen numerischen Wert zuweist, können Sie den Ausgabeversionscode mit einem Wert überschreiben, der den im Block defaultConfig
oder productFlavors
definierten Versionscode mit dem numerischen Wert kombiniert, der der Dichte oder dem ABI zugewiesen ist.
Im folgenden Beispiel erhält die APK für die x86
ABI die versionCode
2004 und die x86_64
ABI die versionCode
3004.
Wenn Sie Versionscodes in großen Schritten wie 1.000 zuweisen, können Sie später eindeutige Versionscodes zuweisen, wenn Sie Ihre App aktualisieren müssen. Wenn defaultConfig.versionCode
beispielsweise bei einem nachfolgenden Update auf 5 iteriert, weist Gradle dem x86
APK den versionCode
2005 und dem x86_64
APK den versionCode
3005 zu.
Tipp:Wenn Ihr Build ein universelles APK enthält, weisen Sie ihm eine versionCode
zu, die niedriger ist als die aller anderen APKs.
Da im Google Play Store die Version Ihrer App installiert wird, die sowohl mit dem Zielgerät kompatibel ist als auch die höchste versionCode
hat, wird durch die Zuweisung einer niedrigeren versionCode
für das universelle APK sichergestellt, dass der Google Play Store versucht, eines Ihrer APKs zu installieren, bevor er auf das universelle APK zurückgreift. Im folgenden Beispielcode wird dies dadurch verhindert, dass die Standard-versionCode
eines universellen APKs nicht überschrieben wird.
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] // 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)) } } } }
Weitere Beispiele für alternative Versionscode-Schemata finden Sie unter Versionscodes zuweisen.
Mehrere APKs erstellen
Nachdem Sie die build.gradle
- oder build.gradle.kts
-Datei auf Modulebene für das Erstellen mehrerer APKs konfiguriert haben, klicken Sie auf Build > APK erstellen, um alle APKs für das aktuell ausgewählte Modul im Bereich Projekt zu erstellen. Gradle erstellt die APKs für jede Dichte oder jedes ABI im Verzeichnis build/outputs/apk/
des Projekts.
Gradle erstellt ein APK für jede Dichte oder jedes ABI, für das Sie mehrere APKs konfigurieren. Wenn Sie mehrere APKs sowohl für Dichten als auch für ABIs aktivieren, erstellt Gradle für jede Kombination aus Dichte und ABI ein APK.
Mit dem folgenden build.gradle
-Snippet können beispielsweise mehrere APKs für die Dichten mdpi
und hdpi
sowie die ABIs x86
und x86_64
erstellt werden:
Groovy
... 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") } }
Die Ausgabe der Beispielkonfiguration enthält die folgenden vier APKs:
app-hdpiX86-release.apk
: Enthält Code und Ressourcen für diehdpi
-Dichte und dasx86
-ABI.app-hdpiX86_64-release.apk
: Enthält Code und Ressourcen für diehdpi
-Dichte und dasx86_64
-ABI.app-mdpiX86-release.apk
: Enthält Code und Ressourcen für diemdpi
-Dichte und dasx86
-ABI.app-mdpiX86_64-release.apk
: Enthält Code und Ressourcen für diemdpi
-Dichte und dasx86_64
-ABI.
Wenn Sie mehrere APKs basierend auf der Bildschirmdichte erstellen, generiert Gradle zusätzlich zu den APKs für jede Dichte immer ein universelles APK, das Code und Ressourcen für alle Dichten enthält.
Wenn Sie mehrere APKs basierend auf dem ABI erstellen, generiert Gradle nur ein APK mit Code und Ressourcen für alle ABIs, wenn Sie in der Datei build.gradle
(für Groovy) im Block splits.abi
die Zeichenfolge universalApk true
oder in der Datei build.gradle.kts
(für Kotlin-Script) im Block splits.abi
die Zeichenfolge isUniversalApk = true
angeben.
Format des APK-Dateinamens
Wenn Sie mehrere APKs erstellen, generiert Gradle APK-Dateinamen nach dem folgenden Schema:
modulename-screendensityABI-buildvariant.apk
Die Schemakomponenten sind:
-
modulename
- Gibt den Namen des zu erstellenden Moduls an.
-
screendensity
-
Wenn mehrere APKs für die Bildschirmdichte aktiviert sind, gibt dies die Bildschirmdichte für das APK an, z. B.
mdpi
. -
ABI
-
Wenn mehrere APKs für ABI aktiviert sind, geben Sie das ABI für das APK an, z. B.
x86
.Wenn mehrere APKs sowohl für die Bildschirmdichte als auch für das ABI aktiviert sind, verknüpft Gradle den Namen der Dichte mit dem Namen des ABI, z. B.
mdpiX86
. WennuniversalApk
für ABI-spezifische APKs aktiviert ist, verwendet Gradleuniversal
als ABI-Teil des Dateinamens des universellen APKs. -
buildvariant
-
Gibt die Buildvariante an, die erstellt wird, z. B.
debug
.
Wenn Sie beispielsweise ein APK mit einer Bildschirmdichte von mdpi
für die Debugversion von „myApp“ erstellen, lautet der APK-Dateiname myApp-mdpi-debug.apk
. Die Releaseversion von „myApp“, die so konfiguriert ist, dass mehrere APKs sowohl für die Bildschirmdichte mdpi
als auch für das ABI x86
erstellt werden, hat die APK-Dateinamen myApp-mdpiX86-release.apk
.