Signiertes Release-Bundle bauen
Application ID festlegen
In
app/build.gradle.ktsidentifiziertapplicationIdindefaultConfigdie App bei Google Play und kann sich nach dem ersten Upload nicht mehr ändern.namespacegilt nur für den Code und darf abweichen.In Android Studio bauen
Wähle Build → Generate Signed Bundle/APK, dann Android App Bundle, wähle Keystore und Schlüssel (oder Create new), die Build-Variante release und klicke auf Create.
Oder über die Kommandozeile
Sobald die Signatur in Gradle eingerichtet ist (nächster Abschnitt), führe den Task unten aus. Das Bundle landet in
app/build/outputs/bundle/release/.
./gradlew bundleReleaseInstalliere die Release-Variante vor dem Upload auf einem Gerät. Fehler durch R8 oder reine Release-Konfiguration zeigen sich in einem Debug-Lauf nie:
./gradlew installReleaseUpload-Schlüssel und Play App-Signatur
Neue Apps müssen die Play App-Signatur nutzen: Google verwahrt den App-Signaturschlüssel, und du signierst jeden Upload mit einem Upload-Schlüssel. Der Assistent in Android Studio kann den Keystore anlegen; er empfiehlt eine Gültigkeit von mindestens 25 Jahren.
Um über die Kommandozeile oder in der CI zu signieren, halte die Zugangsdaten in einer keystore.properties außerhalb der Versionsverwaltung und lies sie in app/build.gradle.kts ein:
storePassword=myStorePassword
keyPassword=myKeyPassword
keyAlias=upload
storeFile=/path/to/upload-keystore.jksimport java.io.FileInputStream
import java.util.Properties
val keystoreProperties = Properties().apply {
load(FileInputStream(rootProject.file("keystore.properties")))
}
android {
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
signingConfig = signingConfigs.getByName("release")
}
}
}Sichere den Keystore und beide Passwörter. Geht der Upload-Schlüssel verloren oder wird er geleakt, erstelle einen neuen und beantrage in der Play Console ein Zurücksetzen; der App-Signaturschlüssel bleibt derselbe.
Versionscode und Ziel-API-Level
versionCode muss höher sein als bei jedem Bundle, das du je hochgeladen hast, egal in welchem Track; versionName sehen die Nutzer. Beide stehen in defaultConfig, neben den SDK-Leveln:
android {
compileSdk = 36
defaultConfig {
applicationId = "com.yourcompany.app"
targetSdk = 36
versionCode = 2
versionName = "1.0.1"
}
}Seit dem 31. August 2026 müssen neue Apps und Updates Android 16 (API-Level 36) als Ziel haben. Ein höheres targetSdk schaltet neues Plattformverhalten ein. Apps mit Ziel Android 15 und höher werden randlos (edge-to-edge) dargestellt, und unter Android 16 funktioniert das Abschalten nicht mehr. Prüfe also vor dem Test, dass deine Compose-Screens Window Insets korrekt behandeln.
Kotlin- und Compose-Fallen
- R8 entfernt, was Reflection braucht. Mit
isMinifyEnabled = truekönnen Serialisierungsmodelle, Retrofit- oder Gson-Klassen und manche Dependency-Injection-Setups nur im Release kaputtgehen. Ergänze Keep-Regeln inproguard-rules.pround teste die Release-Variante. - Überraschungen durch Edge-to-Edge. Inhalte unter Status- und Navigationsleiste verdecken Buttons. Nutze auf jedem Screen, den Tester sehen, das Padding von
ScaffoldoderWindowInsets-Modifier. - Debuggable Release. Steht
isDebuggable = trueim Release-Build-Typ, lehnt die Play Console das Bundle ab. - Signatur-Geheimnisse in Git. Direkt in
build.gradle.ktsgeschriebene Passwörter landen im Repository. Halte sie inkeystore.propertiesoder in CI-Secrets. - Native Bibliotheken und 16-KB-Seiten. Reine Kotlin-Apps unterstützen 16-KB-Speicherseiten bereits, aber NDK-Code und Bibliotheken mit
.so-Dateien müssen neu gebaut oder aktualisiert werden. Die Play Console warnt davor, und ab dem 1. Februar 2027 lassen sich Updates ohne Unterstützung nicht mehr veröffentlichen. - Nur Debug testen. Tester bekommen die Release-Variante. Führe sie vor jedem Upload auf mindestens einer aktuellen Android-Version aus.
Lesbare Stacktraces: R8-Mapping und native Symbole
Tester führen immer nur die Release-Variante aus, ihre Abstürze stammen also aus R8-optimiertem Code mit umbenannten Klassen und Methoden. Der Build schreibt das Mapping, das das rückgängig macht, nach app/build/outputs/mapping/release/mapping.txt, überschreibt es bei jedem Build und packt es zusätzlich ins .aab.
Die Play Console entschleiern lassen
Ab Android Gradle Plugin 4.1 übernimmt die Play Console die Mapping-Datei aus dem hochgeladenen Bundle. Abstürze unter Beobachten und verbessern → Android Vitals → Abstürze und ANRs zeigen dann deine echten Klassen- und Methodennamen.
Pro Release eine Kopie aufbewahren
Archiviere
mapping.txtmit jedem hochgeladenen Versionscode. Du brauchst sie für Stacktraces, die Tester in Fehlerberichte kopieren, und für jedes Absturz-Tool außerhalb von Google Play.Von Hand zurückübersetzen
Führe
retraceaus den Kommandozeilen-Tools mit dem Mapping und einer Datei mit dem Stacktrace aus. Aktuelle Android-Studio-Versionen übersetzen Stacktraces in Logcat auch automatisch zurück.
$ANDROID_HOME/cmdline-tools/latest/bin/retrace \
app/build/outputs/mapping/release/mapping.txt trace.txtNutzt du das NDK? Setze debugSymbolLevel im Release-Build-Typ. SYMBOL_TABLE liefert Funktionsnamen in der Play Console, FULL zusätzlich Dateien und Zeilennummern. Bei App Bundles werden die nativen Symbole automatisch eingebunden und hochgeladen.
android {
buildTypes {
release {
ndk {
debugSymbolLevel = "FULL" // or "SYMBOL_TABLE"
}
}
}
}Behält R8 Code, den du nicht erwartet hast, oder entfernt es Code, den Reflection braucht, zeigt -whyareyoukeeping den Pfad von einer behaltenen Klasse zu einem Einstiegspunkt, und configuration.txt neben dem Mapping listet alle zusammengeführten Regeln.
Play Console kurz: vom geschlossenen Test zur Produktion
Sobald dein Kotlin / Jetpack Compose-Bundle gebaut und signiert ist, passiert der Rest in der Play Console und funktioniert für jedes Framework gleich. Hier die Checkliste; jedes Menü und jeden Bildschirm erklärt die vollständige Play-Console-Anleitung.
- App-Einrichtung abschließen: im Dashboard Datenschutzerklärung, App-Zugriff, Werbung, Altersfreigabe, Zielgruppe, Datensicherheit und Store-Eintrag.
- Release für den geschlossenen Test erstellen: unter Testen und veröffentlichen → Tests → Geschlossene Tests die Länder deiner Tester wählen, das
.aabhochladen und zur Prüfung senden. - Tester per Google Group hinzufügen: im Tab Tester die Gruppe eintragen und den Opt-in-Link teilen. Er funktioniert, sobald der Track Veröffentlicht zeigt.
- Mindestens 12 Tester 14 Tage ohne Unterbrechung im Opt-in halten. Interne Tests zählen nicht, und wer austritt und wiederkommt, beginnt seine 14 Tage von vorn.
- Während des Tests mindestens ein Update veröffentlichen und notieren, was Tester gefunden und was du geändert hast.
- Produktionszugang beantragen: im Dashboard den Antrag öffnen und die drei Abschnitte zu deinem Test, deiner App und deiner Produktionsreife beantworten. Die Entscheidung trifft Google; niemand kann eine Freigabe garantieren.
Plane Ausfälle ein: Gewinne mehr als 12 Tester, damit ein Abgang deinen Zeitplan nicht verschiebt. Alle Play-Console-Schritte ansehen.
Die vollständige Play-Console-Anleitung
Geschlossener Track, Google Group und Opt-in-Link, die Regel 12 Tester / 14 Tage und der Produktionsantrag, Schritt für Schritt auf einer Seite.
Genau das Bundle testen und Updates ausliefern
Erhöhe versionCode, baue das Bundle neu (Gradle oder der Assistent in Android Studio) und lade es in denselben geschlossenen Track hoch.
./gradlew bundleReleaseUm das Bundle zu installieren, das du gleich hochlädst, erzeuge daraus mit bundletool gerätespezifische APKs, signiert mit deinem Upload-Schlüssel. Näher kommst du nicht an das heran, was Google Play ausliefert, einschließlich der Aufteilung nach Bildschirmdichte, Sprache und ABI:
bundletool build-apks --connected-device \
--bundle=app/build/outputs/bundle/release/app-release.aab --output=app.apks \
--ks=/path/to/upload-keystore.jks --ks-key-alias=upload
bundletool install-apks --apks=app.apksFür schnelle Checks im eigenen Team nimmt die interne App-Freigabe der Play Console jeden Versionscode an und liefert einen Download-Link für bis zu 100 Personen. Diese Uploads können nicht Teil eines Test-Tracks sein und ersetzen den geschlossenen Test nicht: Deine 12 Tester installieren immer aus dem geschlossenen Track.
Häufige Fragen
Muss ich mapping.txt selbst hochladen?
Nicht bei App Bundles, die mit Android Gradle Plugin 4.1 oder neuer gebaut wurden: Die Play Console nimmt sie aus dem .aab. APKs brauchen einen manuellen Upload, und Absturz-Tools außerhalb von Google Play brauchen eine eigene Kopie, also archiviere die Datei in jedem Fall.
Ist Minifizierung Pflicht?
Nein. isMinifyEnabled = true ist optional: Es verkleinert und verschleiert deinen Code und ist zugleich der häufigste Grund, warum ein Release-Build abstürzt, während Debug funktioniert. Wenn du es aktivierst, teste die Release-Variante vor jedem Upload.
Müssen Kotlin-Apps etwas für 16-KB-Speicherseiten tun?
Apps, die nur in Kotlin oder Java geschrieben sind, unterstützen 16-KB-Seiten bereits. Mit NDK-Code oder Bibliotheken, die .so-Dateien mitbringen, nutzt du Android Gradle Plugin 8.5.1 oder neuer und NDK r28 oder neuer, aktualisierst diese Bibliotheken und testest auf einem 16-KB-Emulator-Image.
Sollte ich zuerst einen internen Test machen?
Kannst du. Interne Tests sind schnell eingerichtet und gut für einen Smoke-Test mit deinem Team, zählen aber nicht für die Regel der 12 Tester. Lass dich davon also nicht beim geschlossenen Test aufhalten.
Quellen
Die technischen Details wurden mit der offiziellen Dokumentation unten abgeglichen. Menüs und Standardwerte ändern sich zwischen Versionen; im Zweifel gilt die offizielle Seite.
- Android Developers: Sign your app
- Android Developers: Target API level requirements
- Android Developers: Support 16 KB page sizes
- Android Developers: Shrink, obfuscate, and optimize your app
- Android Developers: Troubleshoot app optimization (mapping.txt, retrace)
- Android Developers: Include native debug symbols
- Android Developers: bundletool
- Play Console Help: Internal app sharing
- Play Console Help: App testing requirements for new personal developer accounts
- Play Console Help: Set up an open, closed, or internal test
- Play Console Help: Deobfuscate or symbolicate crash stack traces
Neu bei der Regel mit 12 Testern?
Der allgemeine Leitfaden erklärt Googles Anforderung, wie eine TestBunny-Kampagne Tag für Tag abläuft und was wir garantieren können und was nicht.
Allgemeinen Leitfaden lesen