Mehrere APKs erstellen

Achtung:Seit August 2021 werden alle neuen Apps müssen als App Bundles veröffentlicht sein. Wenn Sie Ihre App bei Google Play veröffentlichen, ein Android App Bundle zu erstellen und hochzuladen. Wann? Wenn Sie dies tun, erstellt Google Play automatisch optimierte APKs für die Gerätekonfiguration der einzelnen Nutzer, sodass sie 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 die Veröffentlichung in einem Speicher erfolgt, der das AAB-Format nicht unterstützt. In diesem Fall Sie müssen jedes APK selbst erstellen, signieren und verwalten.

Obwohl es besser ist, ein einziges APK zu erstellen, das alle Zielgeräte unterstützt kann dies aufgrund von Dateiendungen zu einer sehr großen APK-Datei führen. Unterstützung mehrerer Bildschirmdichten oder Anwendungsbinär Schnittstellen (ABIs) Sie können die Größe Ihres APK reduzieren, indem Sie mehrere APKs enthalten, die Dateien für bestimmte Bildschirmdichten oder ABIs enthalten.

Gradle kann separate APKs erstellen, die nur spezifischen Code und Ressourcen enthalten für jede Dichte oder jedes ABI. Auf dieser Seite wird beschrieben, wie Sie Ihren Build für Mehrere APKs generieren Wenn Sie verschiedene Versionen Ihrer App erstellen müssen die nicht auf Bildschirmdichte oder ABI basieren, verwenden Sie stattdessen Build-Varianten.

Build für mehrere APKs konfigurieren

Wenn du deinen Build für mehrere APKs konfigurieren möchtest, füge ein <ph type="x-smartling-placeholder"></ph> splits-Block zu Ihrer Modulebene build.gradle-Datei. Im splits Block, bitte angeben Einen density-Block, der angibt, wie Gradle generiert werden soll APKs pro Dichte oder einen abi-Block, der angibt, wie Gradle um APKs pro ABI zu generieren. Sie können sowohl Dichte- als auch ABI-Blöcke angeben. erstellt das Build-System ein APK für jede Kombination aus Dichte und ABI.

Mehrere APKs für Bildschirmdichten konfigurieren

Um separate APKs für verschiedene Bildschirmdichten zu erstellen, füge ein density-Block in deinem Block splits Geben Sie im density-Block ein Liste der gewünschten Bildschirmdichten und kompatiblen Bildschirmgrößen. Nur die Liste mit Bildschirmgrößen geeignet ist, wenn Sie <ph type="x-smartling-placeholder"></ph> <compatible-screens>-Elemente im Manifest der einzelnen APKs.

Mit den folgenden Gradle DSL-Optionen werden mehrere APKs für Bildschirmdichten:

enable für Groovy, isEnable für Kotlin-Script
Wenn du dieses Element auf true setzt, generiert Gradle mehrere APKs. Bildschirmdichten festlegen. Der Standardwert ist false
exclude
Gibt eine durch Kommas getrennte Liste der Punktdichten an, die Gradle nicht verwenden soll zum Generieren separater APKs. Verwende exclude, wenn du möchten APKs für die meisten Dichten generieren, müssen aber einige und Dichten, die von deiner App nicht unterstützt werden.
reset()

Löscht die Standardliste mit Kompaktheitsgraden. Nur in Kombination mit dem include-Element, um die gewünschten Dichten anzugeben. hinzufügen.

Mit dem folgenden Snippet wird die Liste der Dichten auf ldpi und xxhdpi durch Anruf bei reset() um die Liste zu löschen, und verwenden Sie dann include:

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 der Dichten an, die Gradle generieren soll APKs für. Nur in Kombination mit reset() verwenden, um Folgendes anzugeben: eine genaue Liste der Dichten.
compatibleScreens

Gibt eine durch Kommas getrennte Liste kompatibler Bildschirmgrößen an. Dieses schleudert ein übereinstimmender <compatible-screens>-Knoten im Manifest für für jedes APK.

Diese Einstellung bietet eine bequeme Möglichkeit, Dichten und Bildschirmgrößen im selben build.gradle-Abschnitt. Wenn Sie jedoch <compatible-screens> kann die Gerätetypen einschränken mit denen Ihre App funktioniert. Alternative Möglichkeiten zur Unterstützung unterschiedlicher Bildschirmgrößen finden Sie Bildschirmkompatibilität.

Da jedes APK, das auf der Bildschirmdichte basiert, ein <compatible-screens> Tag mit bestimmten Einschränkungen welche Bildschirmtypen das APK unterstützt – auch wenn du mehrere APKs: Einige neue Geräte entsprechen nicht Ihren APK-Filtern. Daher Gradle generiert immer ein zusätzliches universelles APK, das Assets enthält. für alle Bildschirmdichten und enthält kein <compatible-screens>-Tag. Veröffentlichen universelles APK zusammen mit Ihren APKs pro Dichte als Fallback für Geräte, die nicht mit den APKs übereinstimmen, <compatible-screens>-Tag.

Im folgenden Beispiel wird für jedes Bildschirm density außer ldpi, xxhdpi und xxxhdpi Dazu verwenden Sie exclude zum Entfernen drei Dichten aus der Standardliste aller Dichten.

Cool

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 Builds Varianten deiner App für bestimmte Bildschirmtypen und Geräte, siehe Deklarieren als eingeschränkt Bildschirmunterstützung

Mehrere APKs für ABIs konfigurieren

Füge einen abi-Block hinzu, um separate APKs für verschiedene ABIs zu erstellen in Ihrem Block splits Geben Sie im abi-Block eine Liste mit gewünschte ABIs.

Mit den folgenden Gradle DSL-Optionen können mehrere APKs pro ABI:

enable für Groovy oder isEnable für Kotlin-Script
Wenn Sie dieses Element auf true setzen, generiert Gradle mehrere APKs basierend auf den von dir definierten ABIs. Der Standardwert ist false.
exclude
Gibt eine durch Kommas getrennte Liste von ABIs an, die Gradle nicht verwenden soll separate APKs generieren können. Verwenden Sie exclude, wenn Sie APKs für die meisten ABIs müssen aber einige ABIs ausschließen, die deine App nicht unterstützt Support.
reset()

Löscht die Standardliste von ABIs. Nur in Kombination mit dem include-Element, um die ABIs anzugeben, die du hinzufügen möchtest.

Mit dem folgenden Snippet wird die Liste der ABIs nur auf x86 und x86_64 durch Aufrufen von reset(), um die Liste zu löschen, und dann mit 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
Gibt eine durch Kommas getrennte Liste von ABIs an, die Gradle APKs generieren soll für die Sie angegeben haben. Nur in Kombination mit reset() verwenden, um eine genaue Liste der ABIs.
universalApk für Groovy oder isUniversalApk für Kotlin-Script

Wenn true festgelegt ist, generiert Gradle neben der APKs pro ABI. Ein universelles APK enthält Code und Ressourcen für alle ABIs in einem für ein einzelnes APK. Der Standardwert ist false.

Beachten Sie, dass diese Option nur verfügbar im Block splits.abi. Beim Erstellen mehrerer APKs Je nach Bildschirmdichte generiert Gradle immer ein universelles APK, enthält Code und Ressourcen für alle Bildschirmdichten.

Im folgenden Beispiel wird für jede ABI ein separates APK generiert: x86 und x86_64. Dazu wird reset() verwendet. um mit einer leeren Liste von ABIs zu beginnen, gefolgt von include mit einem Liste der ABIs, die jeweils ein APK erhalten.

Cool

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 findest du unter Unterstützt ABIs.

Projekte ohne nativen Code/C++-Code

Bei Projekten ohne nativen Code bzw. ohne C++-Code enthält der Bereich Build-Varianten zwei Spalten: Module und Active Build Variante, wie in Abbildung 1 gezeigt.

Der Bereich „Build-Varianten“
Abbildung 1: Der Bereich Varianten erstellen hat zwei Spalten für Projekte ohne nativer/C++ Code.

Der Wert Active Build Variant (Aktive Build-Variante) für den wird die bereitgestellte und im Editor sichtbare Build-Variante bestimmt. Wenn Sie zwischen den Varianten wechseln möchten, klicken Sie auf die Zelle Active Build Variant (Aktive Build-Variante) eines Moduls und wählen Sie die gewünschte Variante aus dem Listenfeld aus.

Projekte mit nativem Code/C++-Code

Bei Projekten mit nativem Code/C++ Code enthält der Bereich Build-Varianten drei Spalten: Module, Active Build Variante und Aktives ABI, wie in Abbildung 2 dargestellt.

Abbildung 2: Im Bereich Build Variants (Varianten erstellen) wird die Spalte Active ABI (Aktives ABI) für Projekte mit nativem Code/C++ Code.

Der Wert Active Build Variant des Moduls bestimmt die bereitgestellte und im Editor sichtbare Build-Variante. Bei nativen Modulen bestimmt der Wert Active ABI das ABI, das vom Editor und hat keinen Einfluss darauf, was bereitgestellt wird.

So ändern Sie den Build-Typ oder ABI:

  1. Klicken Sie auf die Zelle für Active Build Variant (Aktive Build-Variante). oder Active ABI angezeigt.
  2. Wähle die gewünschte Variante oder das gewünschte ABI aus der Liste aus ein. Es wird automatisch eine neue Synchronisierung ausgeführt.

Wenn Sie eine der Spalten für eine App oder ein Bibliotheksmodul ändern, wird die Änderung auf alle abhängigen Zeilen.

Versionsverwaltung konfigurieren

Wenn Gradle mehrere APKs generiert, hat jedes APK standardmäßig die gleichen Versionsinformationen, wie auf Modulebene angegeben Datei build.gradle oder build.gradle.kts. Da die Im Google Play Store sind nicht mehrere APKs für dieselbe App zulässig, die alle Versionsinformationen angegeben haben, müssen Sie sicherstellen, dass jedes APK eine eigene <ph type="x-smartling-placeholder"></ph> versionCode vor dem Upload in den Play Store.

Sie können die Datei build.gradle auf Modulebene so konfigurieren, versionCode für jedes APK überschreiben. Durch Erstellen einer Zuordnung weist jeder von Ihnen konfigurierten ABI und jeder von Ihnen konfigurierten Dichte einen eindeutigen numerischen Wert zu für mehrere APKs haben, können Sie den Ausgabeversionscode mit einem Wert überschreiben, kombiniert den in defaultConfig definierten Versionscode oder productFlavors-Block mit dem numerischen Wert, der dem oder ABI.

Im folgenden Beispiel hat das APK für das ABI x86 erhält ein versionCode von 2004 und das x86_64 ABI erhält einen versionCode von 3.004.

Die Zuweisung von Versionscodes in großen Schritten wie 1.000 können Sie später eindeutige Versionscodes zuweisen, wenn Sie Ihre App aktualisieren müssen. Für Beispiel: Wenn defaultConfig.versionCode in einer spätere Aktualisierung weist Gradle den Wert versionCode von 2005 x86 APK und 3005 zum x86_64 APK.

Tipp:Wenn Ihr Build ein universelles APK enthält, weisen Sie ihm ein versionCode, der niedriger ist als das aller deiner anderen APKs. Da über den Google Play Store die Version Ihrer App installiert wird, ist mit dem Zielgerät kompatibel und hat den höchsten versionCode, dem dieversionCode verwenden, können Sie sicherstellen, dass der Google Play Store versucht, APKs, bevor Sie auf das universelle APK zurückgreifen. Der folgende Beispielcode das Tag eines universellen APK Standard-versionCode.

Cool

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 Versionscodeschemas finden Sie unter <ph type="x-smartling-placeholder"></ph> Versionscodes zuweisen

Mehrere APKs erstellen

Nachdem Sie die build.gradle auf Modulebene konfiguriert haben, oder build.gradle.kts-Datei zum Erstellen mehrerer APKs, klicken Sie Erstellen > Build-APK, um alle APKs für die aktuelle Version zu erstellen ausgewähltes Modul im Bereich Projekt. Gradle erstellt die APKs für jede Dichte oder jedes ABI in den build/outputs/apk/ des Projekts -Verzeichnis.

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 die Dichte als auch für die ABIs aktivieren, erstellt Gradle ein APK. für jede Kombination aus Dichte und ABI.

Beispiel: Mit dem Snippet build.gradle können mehrere APKs für mdpi und hdpi-Dichten und auch x86- und x86_64-ABIs:

Cool

...
  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 Dichte von hdpi und ABI von x86.
  • app-hdpiX86_64-release.apk: enthält Code und Ressourcen für Dichte von hdpi und ABI von x86_64.
  • app-mdpiX86-release.apk: enthält Code und Ressourcen für Dichte von mdpi und ABI von x86.
  • app-mdpiX86_64-release.apk: enthält Code und Ressourcen für Dichte von mdpi und ABI von x86_64.

Wenn Sie mehrere APKs basierend auf der Bildschirmdichte erstellen, generiert ein universelles APK, das Code und Ressourcen für alle Dichten, zusätzlich zu den APKs pro Dichte.

Wenn Sie mehrere APKs basierend auf ABI generiert Gradle nur ein APK, das Code und Ressourcen für alle ABIs, wenn Sie universalApk true im Feld splits.abi-Block in Ihrer build.gradle-Datei (für Groovy) oder isUniversalApk = true in der splits.abi-Block in Ihrer Datei build.gradle.kts (für Kotlin-Script).

Format des APK-Dateinamens

Beim Erstellen mehrerer APKs generiert Gradle APK-Dateinamen mithilfe der folgenden Schema:

modulename-screendensityABI-buildvariant.apk

Die Schemakomponenten sind:

modulename
Gibt den Namen des Moduls an, das erstellt wird.
screendensity
Gibt den Bildschirm an, wenn mehrere APKs für die Bildschirmdichte aktiviert sind Kompaktheitsgrad für das APK, z. B. mdpi.
ABI

Wenn mehrere APKs für ABI aktiviert sind, wird die ABI für das APK angegeben, z. B. als x86.

Wenn mehrere APKs für Bildschirmdichte und ABI aktiviert sind, Gradle verkettet den Dichtenamen beispielsweise mit dem ABI-Namen. mdpiX86 Wenn universalApk für ABI aktiviert ist APKs verwenden Gradle universal als ABI-Teil des universellen APK. filename.

buildvariant
Gibt die Build-Variante an, die erstellt wird, z. B. debug.

Wenn du beispielsweise das Bildschirmdichte-APK mdpi für das Debug-Version von myApp verwendet, lautet der APK-Dateiname myApp-mdpi-debug.apk. Die Veröffentlichung Version von myApp, die so konfiguriert ist, dass mehrere APKs für die Die Bildschirmdichte von mdpi und das ABI „x86“ hat den APK-Dateinamen myApp-mdpiX86-release.apk