Build-Varianten konfigurieren

Auf dieser Seite erfahren Sie, wie Sie Buildvarianten konfigurieren, um aus einem einzigen Projekt verschiedene Versionen Ihrer App zu erstellen, und wie Sie Ihre Abhängigkeiten und Signaturkonfigurationen richtig verwalten.

Jede Buildvariante steht für eine andere Version Ihrer App, die Sie erstellen können. Sie können beispielsweise eine kostenlose Version Ihrer App mit begrenzten Inhalten und eine kostenpflichtige Version mit mehr Inhalten erstellen. Sie können auch verschiedene Versionen Ihrer App erstellen, die auf verschiedene Geräte ausgerichtet sind, je nach API-Level oder anderen Gerätevarianten.

Buildvarianten sind das Ergebnis von Gradle, das mithilfe einer bestimmten Reihe von Regeln Einstellungen, Code und Ressourcen kombiniert, die in Ihren Buildtypen und Produktvarianten konfiguriert sind. Sie konfigurieren Build-Varianten zwar nicht direkt, aber die Build-Typen und Produktvarianten, aus denen sie bestehen.

Beispielsweise können in einem Demo-Produkt-Flavor bestimmte Funktionen und Geräteanforderungen festgelegt werden, z. B. benutzerdefinierter Quellcode, Ressourcen und Mindest-API-Levels. Mit dem Build-Typ "Debug" werden andere Build- und Paketeinstellungen angewendet, z. B. Fehlerbehebungsoptionen und Signaturschlüssel. Die Build-Variante, die diese beiden Komponenten kombiniert, ist die Version „demoDebug“ Ihrer Anwendung. Sie enthält eine Kombination aus den Konfigurationen und Ressourcen, die im Produkt-Flavor „Demo“, dem Build-Typ „Debug“ und dem Quellsatz main/ enthalten sind.

Buildtypen konfigurieren

Sie können Buildtypen im Block android der build.gradle.kts-Datei auf Modulebene erstellen und konfigurieren. Wenn Sie ein neues Modul erstellen, werden in Android Studio automatisch die Buildtypen „Debug“ und „Release“ erstellt. Der Debug-Buildtyp wird zwar nicht in der Build-Konfigurationsdatei angezeigt, aber in Android Studio mit debuggable true konfiguriert. So können Sie die App auf sicheren Android-Geräten debuggen und die App-Signatur mit einem generischen Debug-Schlüsselspeicher konfigurieren.

Sie können den Buildtyp „Fehlerbehebung“ Ihrer Konfiguration hinzufügen, wenn Sie bestimmte Einstellungen hinzufügen oder ändern möchten. Im folgenden Beispiel wird ein applicationIdSuffix für den Debug-Buildtyp angegeben und ein Buildtyp vom Typ „Staging“ konfiguriert, der mit den Einstellungen aus dem Debug-Buildtyp initialisiert wird:

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
        ...
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }

        getByName("debug") {
            applicationIdSuffix = ".debug"
            isDebuggable = true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        create("staging") {
            initWith(getByName("debug"))
            manifestPlaceholders["hostName"] = "internal.example.com"
            applicationIdSuffix = ".debugStaging"
        }
    }
}
android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
        ...
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            applicationIdSuffix ".debug"
            debuggable true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.example.com"]
            applicationIdSuffix ".debugStaging"
        }
    }
}

Hinweis:Wenn Sie Änderungen an einer Build-Konfigurationsdatei vornehmen, müssen Sie Ihr Projekt in Android Studio mit der neuen Konfiguration synchronisieren. Wenn Sie Ihr Projekt synchronisieren möchten, klicken Sie in der Benachrichtigungsleiste, die nach einer Änderung angezeigt wird, auf Jetzt synchronisieren oder in der Symbolleiste auf Projekt synchronisieren . Wenn Android Studio Fehler in Ihrer Konfiguration erkennt, wird das Fenster Nachrichten mit einer Beschreibung des Problems angezeigt.

Weitere Informationen zu allen Attributen, die Sie mit Build-Typen konfigurieren können, finden Sie in der Referenz zu BuildType.

Produktvarianten konfigurieren

Das Erstellen von Produktvarianten ähnelt dem Erstellen von Buildtypen. Fügen Sie dem Block productFlavors in Ihrer Build-Konfiguration Produktvarianten hinzu und geben Sie die gewünschten Einstellungen an. Die Produktvarianten unterstützen dieselben Properties wie defaultConfig, da defaultConfig zur Klasse ProductFlavor gehört. Das bedeutet, dass Sie die Basiskonfiguration für alle Varianten im Block defaultConfig angeben können und jede Variante diese Standardwerte ändern kann, z. B. applicationId. Weitere Informationen zur App-ID

Hinweis:Sie müssen weiterhin einen Paketnamen mit dem Attribut package in der Manifestdatei main/ angeben. Sie müssen diesen Paketnamen auch in Ihrem Quellcode verwenden, um auf die R-Klasse zu verweisen oder relative Aktivitäten oder Dienstregistrierungen aufzulösen. So kannst du mit applicationId jedem Produktvariante eine eindeutige ID für die Verpackung und den Vertrieb zuweisen, ohne den Quellcode ändern zu müssen.

Alle Geschmacksrichtungen müssen zu einer benannten Geschmacksdimension gehören, also einer Gruppe von Produktgeschmacksrichtungen. Sie müssen allen Varianten eine Variantendimension zuweisen. Andernfalls wird der folgende Buildfehler angezeigt.

  Error: All flavors must now belong to a named flavor dimension.
  The flavor 'flavor_name' is not assigned to a flavor dimension.

Wenn für ein bestimmtes Modul nur eine Flavor-Dimension angegeben ist, weist das Android Gradle-Plug-in dieser Dimension automatisch alle Flavors des Moduls zu.

Im folgenden Codebeispiel wird eine Variante mit dem Namen „version“ erstellt und die Produktvarianten „demo“ und „full“ hinzugefügt. Diese Varianten haben eigene applicationIdSuffix und versionNameSuffix:

android {
    ...
    defaultConfig {...}
    buildTypes {
        getByName("debug"){...}
        getByName("release"){...}
    }
    // Specifies one flavor dimension.
    flavorDimensions += "version"
    productFlavors {
        create("demo") {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension = "version"
            applicationIdSuffix = ".demo"
            versionNameSuffix = "-demo"
        }
        create("full") {
            dimension = "version"
            applicationIdSuffix = ".full"
            versionNameSuffix = "-full"
        }
    }
}
android {
    ...
    defaultConfig {...}
    buildTypes {
        debug{...}
        release{...}
    }
    // Specifies one flavor dimension.
    flavorDimensions "version"
    productFlavors {
        demo {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension "version"
            applicationIdSuffix ".demo"
            versionNameSuffix "-demo"
        }
        full {
            dimension "version"
            applicationIdSuffix ".full"
            versionNameSuffix "-full"
        }
    }
}

Hinweis:Wenn du eine alte App hast, die vor August 2021 erstellt wurde und über APKs bei Google Play vertrieben wird, musst du allen Varianten denselben applicationId-Wert zuweisen und jeder Variante eine andere versionCode zuweisen, wenn du deine App über die Unterstützung für mehrere APKs bei Google Play vertreiben möchtest. Wenn Sie unterschiedliche Varianten Ihrer App als separate Apps bei Google Play anbieten möchten, müssen Sie jeder Variante eine andere applicationId zuweisen.

Nachdem Sie die Produktvarianten erstellt und konfiguriert haben, klicken Sie in der Benachrichtigungsleiste auf Jetzt synchronisieren. Nach Abschluss der Synchronisierung erstellt Gradle automatisch Buildvarianten basierend auf Ihren Buildtypen und Produktvarianten und benennt sie gemäß <product-flavor><Build-Type>. Wenn Sie beispielsweise die Produkt-Varianten „Demo“ und „Vollständig“ erstellt und die standardmäßigen Build-Typen „Debug“ und „Release“ beibehalten haben, erstellt Gradle die folgenden Build-Varianten:

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

Wenn Sie auswählen möchten, welche Buildvariante erstellt und ausgeführt werden soll, klicken Sie auf Build > Buildvariante auswählen und wählen Sie im Menü eine Buildvariante aus. Wenn Sie jede Buildvariante mit eigenen Funktionen und Ressourcen anpassen möchten, müssen Sie Quell-Sets erstellen und verwalten, wie auf dieser Seite beschrieben.

Anwendungs-ID für Buildvarianten ändern

Wenn Sie ein APK oder AAB für Ihre App erstellen, taggen die Build-Tools die App wie im folgenden Beispiel mit der App-ID, die im Block defaultConfig der Datei build.gradle.kts definiert ist. Wenn Sie jedoch verschiedene Versionen Ihrer App erstellen möchten, die als separate Einträge im Google Play Store angezeigt werden, z. B. eine kostenlose und eine Pro-Version, müssen Sie separate Build-Varianten erstellen, die jeweils eine andere App-ID haben.

Definieren Sie in diesem Fall jede Buildvariante als separate Produktvariante. Sie können die Property applicationId für jede Variante innerhalb des productFlavors-Blocks neu definieren oder stattdessen mit applicationIdSuffix ein Segment an die Standard-App-ID anhängen, wie hier gezeigt:

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
        }
    }
}
android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    productFlavors {
        free {
            applicationIdSuffix ".free"
        }
        pro {
            applicationIdSuffix ".pro"
        }
    }
}

In diesem Fall lautet die Anwendungs-ID für den Produkt-Flavor "com.example.myapp.free".

Mit applicationIdSuffix können Sie auch ein Segment anhängen, das auf Ihrem Build-Typ basiert. Hier ein Beispiel:

android {
    ...
    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
        }
    }
}
android {
    ...
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
}

Da Gradle die Buildtypkonfiguration nach dem Produkt-Flavor anwendet, lautet die Anwendungs-ID für die Buildvariante „free debug“ „com.example.myapp.free.debug“. Das ist nützlich, wenn Sie sowohl den Debug- als auch den Release-Build auf demselben Gerät haben möchten, da keine zwei Apps dieselbe Anwendungs-ID haben können.

Wenn Sie eine ältere App (vor August 2021 erstellt) haben, die Sie über APKs bei Google Play vertreiben, und mit demselben App-Eintrag mehrere APKs bereitstellen möchten, die jeweils auf eine andere Gerätekonfiguration ausgerichtet sind, z. B. auf die API-Ebene, müssen Sie für jede Buildvariante dieselbe Anwendungs-ID verwenden, aber jedem APK eine andere versionCode zuweisen. Weitere Informationen findest du unter Unterstützung mehrerer APKs. Die Veröffentlichung mit AABs ist davon nicht betroffen, da dabei ein einzelnes Artefakt mit einem einzelnen Versionscode und einer einzigen Anwendungs-ID verwendet wird.

Tipp:Wenn Sie in Ihrer Manifestdatei auf die Anwendungs-ID verweisen müssen, können Sie den Platzhalter ${applicationId} in einem beliebigen Manifestattribut verwenden. Während eines Builds ersetzt Gradle dieses Tag durch die tatsächliche Anwendungs-ID. Weitere Informationen finden Sie unter Buildvariablen in das Manifest einfügen.

Mehrere Produktvarianten mit Variantendimensionen kombinieren

In einigen Fällen möchten Sie möglicherweise Konfigurationen aus mehreren Produktvarianten kombinieren. Beispielsweise können Sie unterschiedliche Konfigurationen für die Produktvarianten „Vollständig“ und „Demo“ erstellen, die auf API-Ebene basieren. Dazu können Sie mit dem Android Gradle-Plug-in mehrere Gruppen von Produktvarianten als Variantendimensionen erstellen.

Beim Erstellen Ihrer App kombiniert Gradle eine Produkt-Flavor-Konfiguration aus jeder von Ihnen definierten Flavor-Dimension mit einer Build-Typkonfiguration, um die endgültige Build-Variante zu erstellen. Gradle kombiniert keine Produktvarianten, die derselben Variantendimension angehören.

Im folgenden Codebeispiel wird die Property flavorDimensions verwendet, um eine Variante „Modus“ zu erstellen, um die Produktvarianten „Vollständig“ und „Demo“ zu gruppieren, und eine Variante „api“, um Konfigurationen von Produktvarianten basierend auf der API-Ebene zu gruppieren:

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdk = 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.
      versionCode = 30000 + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdk = 23
      versionCode = 20000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdk = 21
      versionCode = 10000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...
android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.

      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion 23
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion 21
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

Die Anzahl der von Gradle erstellten Buildvarianten entspricht dem Produkt aus der Anzahl der Flavors in jeder Flavor-Dimension und der Anzahl der konfigurierten Buildtypen. Wenn Gradle die einzelnen Buildvarianten oder entsprechenden Artefakte benennt, werden zuerst Produktvarianten mit einer höheren Prioritätsdimension angezeigt, gefolgt von denen mit niedrigeren Prioritätsdimensionen und dann vom Buildtyp.

Anhand der vorherigen Build-Konfiguration erstellt Gradle insgesamt zwölf Buildvarianten mit dem folgenden Benennungsschema:

  • Build-Variante: [minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
  • Entsprechendes APK: app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
  • Beispiel:
    Buildvariante: minApi24DemoDebug
    Entsprechendes APK: app-minApi24-demo-debug.apk

Neben den Verzeichnissen für Quellsets, die Sie für jede einzelne Produktvariante und Buildvariante erstellen können, können Sie auch Verzeichnisse für Quellsets für jede Kombination von Produktvarianten erstellen. Sie können beispielsweise Java-Quellen im Verzeichnis src/demoMinApi24/java/ erstellen und hinzufügen. Gradle verwendet diese Quellen dann nur, wenn eine Variante erstellt wird, die diese beiden Produktvarianten kombiniert.

Quellgruppen, die Sie für Kombinationen von Produktvarianten erstellen, haben eine höhere Priorität als Quellgruppen, die zu den einzelnen Produktvarianten gehören. Weitere Informationen zu Quellsätzen und zum Zusammenführen von Ressourcen mit Gradle finden Sie im Abschnitt zum Erstellen von Quellsätzen.

Varianten filtern

Gradle erstellt eine Build-Variante für jede mögliche Kombination der von Ihnen konfigurierten Produktvarianten und Build-Typen. Es kann jedoch bestimmte Buildvarianten geben, die Sie nicht benötigen oder die im Kontext Ihres Projekts keinen Sinn ergeben. Wenn Sie bestimmte Build-Variantenkonfigurationen entfernen möchten, erstellen Sie in der Datei build.gradle.kts auf Modulebene einen Variantenfilter.

Angenommen, Sie möchten für die Demoversion der App nur API-Ebenen 23 und höher unterstützen. Mit dem Block variantFilter können Sie alle Konfigurationen für Buildvarianten herausfiltern, die die Produktvarianten „minApi21“ und „demo“ kombinieren:

android {
  ...
  buildTypes {...}

  flavorDimensions += listOf("api", "mode")
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == "<buildType>"
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enable = false
        }
    }
}
...
android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == "<buildType>"
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

Nachdem Sie Ihrer Build-Konfiguration einen Variantenfilter hinzugefügt und in der Benachrichtigungsleiste auf Jetzt synchronisieren geklickt haben, ignoriert Gradle alle Build-Varianten, die die von Ihnen angegebenen Bedingungen erfüllen. Die Buildvarianten werden nicht mehr im Menü angezeigt, wenn Sie in der Menüleiste auf Build > Buildvariante auswählen oder in der Toolfensterleiste auf Buildvarianten klicken.

Quellsätze erstellen

Standardmäßig erstellt Android Studio das main/ Source Set und die Verzeichnisse für alle Elemente, die Sie für alle Buildvarianten freigeben möchten. Sie können jedoch neue Quellsätze erstellen, um genau zu steuern, welche Dateien Gradle für bestimmte Build-Typen, Produkt-Varianten, Kombinationen von Produkt-Varianten (bei Verwendung von Flavor-Dimensionen) und Build-Varianten kompiliert.

Sie können beispielsweise grundlegende Funktionen im Quellsatz main/ definieren und mit Produkt-Flavor-Quellsets das Branding Ihrer App für verschiedene Clients ändern. Sie können aber auch spezielle Berechtigungen und Logging-Funktionen nur für Build-Varianten einbinden, die den Build-Typ „Debug“ verwenden.

Gradle erwartet, dass Quelldateien und ‑verzeichnisse ähnlich wie das main/-Quellset organisiert sind. Beispielsweise erwartet Gradle, dass sich Kotlin- oder Java-Klassendateien, die für den Buildtyp „debug“ spezifisch sind, in den Verzeichnissen src/debug/kotlin/ oder src/debug/java/ befinden.

Das Android Gradle-Plug-in bietet eine nützliche Gradle-Aufgabe, die Ihnen zeigt, wie Sie Ihre Dateien für jeden Ihrer Build-Typen, Produktvarianten und Build-Varianten organisieren. Im folgenden Beispiel aus der Aufgabenausgabe wird beispielsweise beschrieben, wo Gradle bestimmte Dateien für den Build-Typ „debug“ erwartet:

------------------------------------------------------------
Project :app
------------------------------------------------------------

...

debug
----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

So rufen Sie diese Ausgabe auf:

  1. Klicken Sie in der Symbolleiste des Tool-Fensters auf Gradle.
  2. Gehen Sie zu MyApplication > Tasks > android und doppelklicken Sie auf sourceSets.

    Damit der Ordner Tasks angezeigt wird, muss Gradle die Aufgabenliste während der Synchronisierung erstellen. Führen Sie dazu die folgenden Schritte aus:

    1. Klicken Sie auf Datei > Einstellungen > Experimentell (Android Studio > Einstellungen > Experimentell unter macOS).
    2. Heben Sie die Auswahl der Option Gradle-Aufgabenliste während der Gradle-Synchronisierung nicht erstellen auf.
  3. Nachdem Gradle die Aufgabe ausgeführt hat, wird das Fenster Ausführen geöffnet, in dem die Ausgabe angezeigt wird.

Hinweis: Die Aufgabenausgabe zeigt Ihnen auch, wie Sie Quellsätze für Dateien organisieren, die Sie zum Ausführen von Tests für Ihre Anwendung verwenden möchten, z. B. die Testquellensätze test/ und androidTest/.

Wenn Sie eine neue Build-Variante erstellen, erstellt Android Studio die Verzeichnisse für das Quellset nicht für Sie. Es bietet Ihnen jedoch einige Optionen, die Ihnen dabei helfen können. Wenn Sie beispielsweise nur das Verzeichnis java/ für den Buildtyp „debug“ erstellen möchten, geben Sie Folgendes ein:

  1. Öffnen Sie den Bereich Projekt und wählen Sie oben im Bereich im Menü die Ansicht Projekt aus.
  2. Zu MyProject/app/src/ navigieren
  3. Klicken Sie mit der rechten Maustaste auf das Verzeichnis src und wählen Sie Neu > Verzeichnis aus.
  4. Wählen Sie im Menü unter Gradle-Quellsätze die Option full/java aus.
  5. Drücken Sie die Eingabetaste.

Android Studio erstellt ein Source-Set-Verzeichnis für Ihren Debug-Buildtyp und dann das Verzeichnis java/ darin. Alternativ können Sie die Verzeichnisse auch in Android Studio erstellen, wenn Sie Ihrem Projekt eine neue Datei für eine bestimmte Build-Variante hinzufügen.

So erstellen Sie beispielsweise eine Werte-XML-Datei für den Buildtyp „debug“:

  1. Klicken Sie im Bereich Projekt mit der rechten Maustaste auf das Verzeichnis src und wählen Sie Neu > XML > Values XML-Datei aus.
  2. Geben Sie den Namen für die XML-Datei ein oder belassen Sie den Standardnamen.
  3. Wählen Sie im Menü neben Zielquellen-Set die Option debug aus.
  4. Klicken Sie auf Fertig.

Da der Build-Typ "debug" als Zielquellensatz angegeben wurde, erstellt Android Studio beim Erstellen der XML-Datei automatisch die erforderlichen Verzeichnisse. Die resultierende Verzeichnisstruktur sieht aus wie in Abbildung 1.

Abbildung 1. Neue Verzeichnisse für Quellsätze für den Buildtyp „debug“

Aktive Quellengruppen sind durch ein grünes Symbol gekennzeichnet. Das debug-Quellset hat das Suffix [main], um anzuzeigen, dass es mit dem main-Quellsatz zusammengeführt wird.

Mit demselben Verfahren können Sie auch Verzeichnisse für Quellsätze für Produktvarianten wie src/demo/ erstellen und Varianten wie src/demoDebug/ erstellen. Außerdem können Sie Testquellensätze erstellen, die auf bestimmte Buildvarianten ausgerichtet sind, z. B. src/androidTestDemoDebug/. Weitere Informationen finden Sie unter Quellsätze testen.

Standardkonfigurationen für Quellgruppen ändern

Wenn Ihre Quellen nicht in der von Gradle erwarteten Standarddateistruktur des Quellsatzes organisiert sind, wie im vorherigen Abschnitt zum Erstellen von Quellsätzen beschrieben, können Sie mit dem Block sourceSets ändern, wo Gradle nach Dateien für die einzelnen Komponenten eines Quellsatzes sucht.

Der Block sourceSets muss sich im Block android befinden. Sie müssen die Quelldateien nicht verschieben. Sie müssen Gradle nur den Pfad oder die Pfade relativ zur build.gradle.kts-Datei auf Modulebene angeben, unter dem bzw. denen Gradle Dateien für jede Komponente des Quellsatzes finden kann. Informationen dazu, welche Komponenten Sie konfigurieren können und ob Sie sie mehreren Dateien oder Verzeichnissen zuordnen können, finden Sie in der API-Referenz für das Android Gradle-Plug-in.

Im folgenden Codebeispiel werden Quellen aus dem Verzeichnis app/other/ bestimmten Komponenten des Quellsatzes main zugeordnet und das Stammverzeichnis des Quellsatzes androidTest geändert:

android {
  ...
  // Encapsulates configurations for the main source set.
  sourceSets.getByName("main") {
    // Changes the directory for Java sources. The default directory is
    // 'src/main/java'.
    java.setSrcDirs(listOf("other/java"))

    // If you list multiple directories, Gradle uses all of them to collect
    // sources. Because Gradle gives these directories equal priority, if
    // you define the same resource in more than one directory, you receive an
    // error when merging resources. The default directory is 'src/main/res'.
    res.setSrcDirs(listOf("other/res1", "other/res2"))

    // Note: Avoid specifying a directory that is a parent to one
    // or more other directories you specify. For example, avoid the following:
    // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
    // Specify either only the root 'other/res1' directory or only the
    // nested 'other/res1/layouts' and 'other/res1/strings' directories.

    // For each source set, you can specify only one Android manifest.
    // By default, Android Studio creates a manifest for your main source
    // set in the src/main/ directory.
    manifest.srcFile("other/AndroidManifest.xml")
    ...
  }

  // Create additional blocks to configure other source sets.
  sourceSets.getByName("androidTest") {
      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
  }
}
...
android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // If you list multiple directories, Gradle uses all of them to collect
      // sources. Because Gradle gives these directories equal priority, if
      // you define the same resource in more than one directory, you receive an
      // error when merging resources. The default directory is 'src/main/res'.
      res.srcDirs = ['other/res1', 'other/res2']

      // Note: Avoid specifying a directory that is a parent to one
      // or more other directories you specify. For example, avoid the following:
      // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
      // Specify either only the root 'other/res1' directory or only the
      // nested 'other/res1/layouts' and 'other/res1/strings' directories.

      // For each source set, you can specify only one Android manifest.
      // By default, Android Studio creates a manifest for your main source
      // set in the src/main/ directory.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

Beachten Sie, dass ein Quellverzeichnis nur zu einem Quellsatz gehören kann. Beispielsweise ist es nicht möglich, dieselben Testquellen sowohl für die Quellgruppen test als auch für androidTest freizugeben. Das liegt daran, dass Android Studio separate IntelliJ-Module für jeden Quellsatz erstellt und keine doppelten Inhaltsstämme in Quellsätzen unterstützt.

Mit Quellsätzen erstellen

Sie können Quellsatzverzeichnisse so verwenden, dass sie den Code und die Ressourcen enthalten, die nur mit bestimmten Konfigurationen gepackt werden sollen. Wenn Sie beispielsweise die Buildvariante „demoDebug“ erstellen, die das Kreuzprodukt aus einem „demo“-Produkt-Flavor und dem Buildtyp „debug“ ist, prüft Gradle diese Verzeichnisse und ordnet ihnen die folgende Priorität zu:

  1. src/demoDebug/ (Build-Variante – Quellsatz)
  2. src/debug/ (Build-Typ-Quellsatz)
  3. src/demo/ (Quellsatz für Produktvariante)
  4. src/main/ (Hauptquellensatz)

In Quellgruppen, die für Kombinationen von Produktvarianten erstellt wurden, müssen alle Variantendimensionen enthalten sein. Das Quellset für die Buildvariante muss beispielsweise eine Kombination aus dem Buildtyp und allen Variantendimensionen sein. Das Zusammenführen von Code und Ressourcen mit Ordnern, die mehrere, aber nicht alle Variantendimensionen abdecken, wird nicht unterstützt.

Wenn Sie mehrere Geschmacksrichtungen kombinieren, wird die Priorität der Geschmacksrichtungen durch die Geschmacksdimension bestimmt, zu der sie gehören. Wenn Sie Geschmacksdimensionen mit der Property android.flavorDimensions angeben, haben Produktvarianten, die zur ersten Geschmacksdimension gehören, eine höhere Priorität als diejenigen, die zur zweiten Geschmacksdimension gehören, und so weiter. Darüber hinaus haben Quellsätze, die Sie für Kombinationen von Produkt-Geschmacksrichtungen erstellen, eine höhere Priorität als Quellsätze, die zu einem einzelnen Produkt-Geschmacks gehören.

Die Prioritätsreihenfolge bestimmt, welche Quellgruppe beim Kombinieren von Code und Ressourcen eine höhere Priorität hat. Da das Verzeichnis „demoDebug/“ wahrscheinlich Dateien enthält, die für diese Buildvariante spezifisch sind, verwendet Gradle die Datei im Quellsatz „demoDebug/“, wenn „demoDebug/“ eine Datei enthält, die auch in „debug/“ definiert ist. Ebenso ordnet Gradle Dateien in den Build-Typen und Produktvarianten-Quelldateien eine höhere Priorität zu als denselben Dateien in main/. Gradle berücksichtigt diese Prioritätsreihenfolge, wenn die folgenden Build-Regeln angewendet werden:

  • Der gesamte Quellcode in den Verzeichnissen kotlin/ oder java/ wird zusammen kompiliert, um eine einzelne Ausgabe zu generieren.

    Hinweis:Bei einer bestimmten Build-Variante gibt Gradle einen Build-Fehler aus, wenn zwei oder mehr Quellsatz-Verzeichnisse gefunden werden, in denen dieselbe Kotlin- oder Java-Klasse definiert ist. Wenn Sie beispielsweise eine Debug-App erstellen, können Sie weder src/debug/Utility.kt noch src/main/Utility.kt definieren, da Gradle während des Build-Prozesses beide Verzeichnisse überprüft und einen Fehler vom Typ „Duplizierte Klasse“ auslöst. Wenn Sie verschiedene Utility.kt-Versionen für verschiedene Build-Typen verwenden möchten, muss jeder Build-Typ eine eigene Version der Datei definieren und nicht in den main/-Quellsatz aufnehmen.

  • Manifeste werden zu einem einzigen Manifest zusammengeführt. Die Priorität wird in derselben Reihenfolge wie in der Liste im vorherigen Beispiel angegeben. Das heißt, die Manifesteinstellungen für einen Build-Typ überschreiben die Manifesteinstellungen für einen Produkt-Flavor usw. Weitere Informationen finden Sie unter Manifeste zusammenführen.
  • Dateien in den values/-Verzeichnissen werden zusammengeführt. Wenn zwei Dateien denselben Namen haben, z. B. zwei strings.xml-Dateien, wird die Priorität in der Reihenfolge wie in der Liste im vorherigen Beispiel vergeben. Das heißt, Werte, die in einer Datei im Quellsatz des Build-Typs definiert sind, überschreiben die Werte, die in derselben Datei in einem Produkt-Flavor definiert wurden, usw.
  • Ressourcen in den Verzeichnissen res/ und asset/ werden zusammen verpackt. Wenn Ressourcen mit demselben Namen in zwei oder mehr Quellsätzen definiert sind, wird die Priorität in derselben Reihenfolge wie in der Liste im vorherigen Beispiel zugewiesen.
  • Gradle ordnet Ressourcen und Manifeste, die in Bibliotheksmodulabhängigkeiten enthalten sind, beim Erstellen der App die niedrigste Priorität zu.

Abhängigkeiten deklarieren

Wenn Sie eine Abhängigkeit für eine bestimmte Build-Variante oder einen Testquellensatz konfigurieren möchten, stellen Sie den Namen der Build-Variante oder des Testquellensatzes vor dem Schlüsselwort Implementation vor, wie im folgenden Beispiel gezeigt:

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    "freeImplementation"(project(":mylibrary"))

    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.6.1")
}
dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    freeImplementation project(":mylibrary")

    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.6.1'
}

Weitere Informationen zum Konfigurieren von Abhängigkeiten finden Sie unter Build-Abhängigkeiten hinzufügen.

Variantenspezifische Abhängigkeitsverwaltung verwenden

Das Android Gradle-Plug-in 3.0.0 und höher enthält einen neuen Abhängigkeitsmechanismus, der beim Verwenden einer Bibliothek automatisch Varianten abgleicht. Das bedeutet, dass die debug-Variante einer App automatisch die debug-Variante einer Bibliothek nutzt usw. Das funktioniert auch bei der Verwendung von Varianten: Die freeDebug-Variante einer App verwendet die freeDebug-Variante einer Bibliothek.

Damit das Plug-in Varianten korrekt abgleichen kann, müssen Sie wie im folgenden Abschnitt beschrieben entsprechende Fallbacks angeben, falls keine direkte Übereinstimmung möglich ist.

Angenommen, Sie konfigurieren in Ihrer App einen Build-Typ namens „Staging“, aber eine ihrer Bibliotheksabhängigkeiten nicht. Wenn das Plug-in versucht, die Staging-Version Ihrer App zu erstellen, weiß es nicht, welche Version der Bibliothek verwendet werden soll. Sie erhalten dann eine Fehlermeldung ähnlich der folgenden:

Error:Failed to resolve: Could not resolve project :mylibrary.
Required by:
    project :app

Build-Fehler im Zusammenhang mit der Variantenabgleichung beheben

Das Plug-in enthält DSL-Elemente, mit denen Sie steuern können, wie Gradle Situationen löst, in denen eine direkte Übereinstimmung zwischen einer App und einer Abhängigkeit nicht möglich ist.

Im Folgenden finden Sie eine Liste von Problemen im Zusammenhang mit dem variantenbasierten Abhängigkeitsabgleich und wie sie mithilfe von DSL-Eigenschaften behoben werden können:

  • Ihre App enthält einen Build-Typ, den eine Bibliothekabhängigkeit nicht hat.

    Ihre App enthält beispielsweise den Buildtyp „Staging“, eine Abhängigkeit jedoch nur die Buildtypen „Debug“ und „Release“.

    Es liegt kein Problem vor, wenn eine Bibliothek abhängig von einem Buildtyp ist, den Ihre App nicht hat. Das liegt daran, dass das Plug-in diesen Build-Typ niemals aus der Abhängigkeit anfordert.

    Verwenden Sie matchingFallbacks, um alternative Übereinstimmungen für einen bestimmten Buildtyp anzugeben, wie hier gezeigt:

    // In the app's build.gradle.kts file.
    android {
        buildTypes {
            getByName("debug") {}
            getByName("release") {}
            create("staging") {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks += listOf("debug", "qa", "release")
            }
        }
    }
    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {}
            release {}
            staging {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks = ['debug', 'qa', 'release']
            }
        }
    }
  • Für eine bestimmte Variante, die sowohl in der App als auch in der Bibliotheksabhängigkeit vorhanden ist, enthält Ihre App Varianten, die in der Bibliothek nicht vorhanden sind.

    Beispiel: Sowohl Ihre App als auch ihre Bibliotheksabhängigkeiten enthalten die Variante „Tier“. Die Dimension „Stufen“ in der App enthält jedoch die Varianten „kostenlos“ und „kostenpflichtig“, während eine Abhängigkeit für dieselbe Dimension nur die Varianten „Demo“ und „kostenpflichtig“ enthält.

    Hinweis: Bei einer bestimmten Variante, die sowohl in der App als auch in den Bibliotheksabhängigkeiten vorhanden ist, liegt kein Problem vor, wenn eine Bibliothek eine Produktvariante enthält, die in Ihrer App nicht vorhanden ist. Das liegt daran, dass das Plug-in diese Variante nie von der Abhängigkeit anfordert.

    Verwende matchingFallbacks, um alternative Übereinstimmungen für die „kostenlose“ Produktvariante der App anzugeben, wie hier gezeigt:

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions += "tier"
        productFlavors {
            create("paid") {
                dimension = "tier"
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            create("free") {
                dimension = "tier"
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks += listOf("demo", "trial")
            }
        }
    }
    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions 'tier'
        productFlavors {
            paid {
                dimension 'tier'
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            free {
                dimension 'tier'
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks = ['demo', 'trial']
            }
        }
    }
  • Eine Bibliotheksabhängigkeit enthält eine Flavor-Dimension, die Ihre App nicht enthält.

    Eine Bibliotheksabhängigkeit enthält beispielsweise Varianten für die Dimension „minApi“, Ihre App jedoch nur Varianten für die Dimension „Tier“. Wenn Sie die Version „freeDebug“ Ihrer App erstellen möchten, weiß das Plug-in nicht, ob die Version „minApi23Debug“ oder „minApi18Debug“ der Abhängigkeit verwendet werden soll.

    Wenn Ihre App eine Flavor-Dimension enthält, die es bei einer Bibliotheksabhängigkeit nicht der Fall ist, gibt es kein Problem. Das liegt daran, dass das Plug-in nur die Varianten der Dimensionen abgleicht, die in der Abhängigkeit vorhanden sind. Wenn eine Abhängigkeit beispielsweise keine Dimension für ABIs enthält, wird in der Version „freeX86Debug“ Ihrer App die Version „freeDebug“ der Abhängigkeit verwendet.

    Verwenden Sie missingDimensionStrategy im Block defaultConfig, um den Standard-Flavor für das Plug-in anzugeben, der aus jeder fehlenden Dimension ausgewählt werden soll, wie im folgenden Beispiel gezeigt. Sie können Ihre Auswahl im Block productFlavors auch überschreiben, damit jede Variante eine andere Abgleichsstrategie für eine fehlende Dimension angeben kann.

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy("minApi", "minApi18", "minApi23")
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy("abi", "x86", "arm64")
        }
        flavorDimensions += "tier"
        productFlavors {
            create("free") {
                dimension = "tier"
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the "minApi" dimension.
                missingDimensionStrategy("minApi", "minApi23", "minApi18")
            }
            create("paid") {}
        }
    }
    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy 'abi', 'x86', 'arm64'
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the 'minApi' dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
            }
            paid {}
        }
    }

Weitere Informationen finden Sie in der Android Gradle-Plug-in-DSL-Referenz unter matchingFallbacks und missingDimensionStrategy.

Signatureinstellungen konfigurieren

Gradle signiert nur dann das APK oder AAB Ihres Release-Builds, wenn Sie explizit eine Signaturkonfiguration für diesen Build definieren. Falls du noch keinen Signaturschlüssel hast, kannst du mit Android Studio einen Uploadschlüssel und einen Schlüsselspeicher generieren.

So konfigurieren Sie die Signaturkonfigurationen für Ihren Release-Buildtyp manuell mit Gradle-Buildkonfigurationen:

  1. Erstellen Sie einen Schlüsselspeicher. Ein Schlüsselspeicher ist eine Binärdatei, die eine Reihe privater Schlüssel enthält. Sie müssen den Schlüsselspeicher an einem sicheren Ort aufbewahren.
  2. Erstellen Sie einen privaten Schlüssel. Mit einem privaten Schlüssel wird Ihre App für den Vertrieb signiert. Er ist niemals in der App enthalten und wird nicht an unbefugte Dritte weitergegeben.
  3. Fügen Sie der Datei build.gradle.kts auf Modulebene die Signaturkonfiguration hinzu:

    ...
    android {
        ...
        defaultConfig {...}
        signingConfigs {
            create("release") {
                storeFile = file("myreleasekey.keystore")
                storePassword = "password"
                keyAlias = "MyReleaseKey"
                keyPassword = "password"
            }
        }
        buildTypes {
            getByName("release") {
                ...
                signingConfig = signingConfigs.getByName("release")
            }
        }
    }
    ...
    android {
        ...
        defaultConfig {...}
        signingConfigs {
            release {
                storeFile file("myreleasekey.keystore")
                storePassword "password"
                keyAlias "MyReleaseKey"
                keyPassword "password"
            }
        }
        buildTypes {
            release {
                ...
                signingConfig signingConfigs.release
            }
        }
    }

Hinweis: Es ist keine gute Sicherheitsmaßnahme, die Passwörter für den Releaseschlüssel und den Schlüsselspeicher in die Build-Datei aufzunehmen. Konfigurieren Sie stattdessen die Build-Datei so, dass diese Passwörter aus Umgebungsvariablen abgerufen werden, oder lassen Sie sich während des Build-Prozesses nach diesen Passwörtern fragen.

So rufen Sie diese Passwörter aus Umgebungsvariablen ab:

storePassword = System.getenv("KSTOREPWD")
keyPassword = System.getenv("KEYPWD")
storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")

Alternativ können Sie den Schlüsselspeicher aus einer lokalen Eigenschaftendatei laden. Fügen Sie diese Datei aus Sicherheitsgründen nicht der Versionskontrolle hinzu. Richten Sie es stattdessen lokal für jeden Entwickler ein. Weitere Informationen finden Sie im Hilfeartikel Unterzeichnungsinformationen aus Ihren Build-Dateien entfernen.

Wenn dieser Vorgang abgeschlossen ist, kannst du deine App vertreiben und bei Google Play veröffentlichen.

Warnung:Bewahren Sie den Schlüsselspeicher und den privaten Schlüssel an einem sicheren Ort auf und sorgen Sie für sichere Back-ups. Wenn Sie die Play App-Signatur verwenden und Ihren Uploadschlüssel verlieren, können Sie über die Play Console einen Zurücksetzungsvorgang anfordern. Wenn Sie eine App ohne Play App-Signatur veröffentlichen (für Apps, die vor August 2021 erstellt wurden) und den App-Signaturschlüssel verlieren, können Sie keine Updates für Ihre App veröffentlichen, da Sie immer alle Versionen Ihrer App mit demselben Schlüssel signieren müssen.

Wear OS-Apps signieren

Beim Veröffentlichen von Wear OS-Apps müssen sowohl das Smartwatch-APK als auch das optionale Smartphone-APK mit demselben Schlüssel signiert sein. Weitere Informationen zum Paketieren und Signieren von Wear OS-Apps finden Sie unter Wear OS-Apps im Paket anbieten und vertreiben.