Jetpack Compose führt Ihren Code in mehreren verschiedenen Phasen aus, wodurch einige Teile der @Composable-Funktion separat voneinander ausgeführt werden. Abstürze in diesen Phasen können zu schwer nachvollziehbaren Stacktraces führen, sodass es schwierig ist, die genaue Funktion oder Codezeile zu ermitteln, die den Absturz verursacht hat.
Quellinformationen zu Stacktraces hinzufügen
Um die Lesbarkeit von Stacktraces zu verbessern, bietet eine Opt-in-API detailliertere Informationen zum Absturzort, einschließlich Namen und Speicherorten von Composables. So können Sie:
- Absturzursachen effizient identifizieren und beheben
- Abstürze für reproduzierbare Beispiele isolieren
- Abstürze untersuchen, bei denen zuvor nur interne Stackframes angezeigt wurden
Die Compose-Laufzeit kann den Absturzort in der Komposition erkennen und einen Stacktrace basierend auf Ihrer @Composable-Hierarchie rekonstruieren. Der Stacktrace wird bei Abstürzen in folgenden Bereichen angehängt:
- Komposition
DisposableEffectundLaunchedEffect(mit Ausnahme vononDisposeoder Kündigung)- In
rememberCoroutineScopegestartete Coroutinen - Passen messen, anordnen und zeichnen
Fügen Sie die folgenden Zeilen in den Einstiegspunkt der Anwendung ein, um diese Funktion zu aktivieren:
// Enable stack traces at application level: onCreate class SampleStackTracesEnabledApp : Application() { override fun onCreate() { super.onCreate() // Enable Compose stack traces for minified builds only. Composer.setDiagnosticStackTraceMode(ComposeStackTraceMode.Auto) // Alternatively: // Enable verbose Compose stack traces for local debugging Composer.setDiagnosticStackTraceMode(ComposeStackTraceMode.SourceInformation) } }
Idealerweise führen Sie diese Konfiguration aus, bevor Sie Kompositionen erstellen, um zu prüfen, ob die Informationen zum Stacktrace richtig erfasst werden.
Für die ComposeStackTraceMode gibt es vier Optionen:
Auto: Empfohlene Option, daGroupKeysverwendet wird, wenn die App minimiert ist, undNoneandernfalls.GroupKeys: Stacktraces werden für minimierte Apps erstellt. Die Informationen zum Gruppenschlüssel bleiben auch nach der Minimierung erhalten und werden zusammen mit der ProGuard-Zuordnungsdatei, die vom Compose-Compiler und R8 ausgegeben wird, verwendet, um eine ungefähre Position von@Composable-Funktionen zu rekonstruieren. Diese Stacktraces sind weniger präzise und darauf optimiert, zusätzliche Arbeit zur Laufzeit zu vermeiden. Der Compose-Compiler unterstützt ab Kotlin 2.3.0 die Ausgabe zusätzlicher R8-Mappings.SourceInformation: Nützlich für nicht minimierte Builds. Erfasst Quellinformationen und fügt sie dem Stacktrace hinzu. Die Ergebnisse sind genauer, verursachen aber einen erheblichen Leistungsaufwand, der dem Anfügen des Layoutinspektors ähnelt. Sie werden für Debug-Versionen der Apps erstellt, um genaue Informationen zu einem Absturz zu erhalten, für den weitere Informationen zum Speicherort erforderlich sind. Die Quellinformationen werden aus minimierten Apps entfernt, um die Binärgröße und die Leistung zu optimieren.None: Es wurden keine zusätzlichen Stacktrace-Details hinzugefügt.
Wenn Sie die Option SourceInformation verwenden, wird der Stacktrace als DiagnosticComposeException in der Liste der unterdrückten Ausnahmen angezeigt:
java.lang.IllegalStateException: Test layout error
at <original trace>
Suppressed: androidx.compose.runtime.DiagnosticComposeException:
Composition stack when thrown:
at ReusableComposeNode(Composables.kt:<unknown line>)
at Layout(Layout.kt:79)
at <lambda>(TempErrorsTest.kt:164)
at <lambda>(BoxWithConstraints.kt:66)
at ReusableContentHost(Composables.kt:164)
at <lambda>(SubcomposeLayout.kt:514)
at SubcomposeLayout(SubcomposeLayout.kt:114)
at SubcomposeLayout(SubcomposeLayout.kt:80)
at BoxWithConstraints(BoxWithConstraints.kt:64)
at SubcomposeLayoutErrorComposable(TempErrorsTest.kt:164)
at <lambda>(TempErrorsTest.kt:86)
at Content(ComposeView.android.kt:430)
at <lambda>(ComposeView.android.kt:249)
at CompositionLocalProvider(CompositionLocal.kt:364)
at ProvideCommonCompositionLocals(CompositionLocals.kt:193)
at <lambda>(AndroidCompositionLocals.android.kt:113)
at CompositionLocalProvider(CompositionLocal.kt:364)
at ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:102)
at <lambda>(Wrapper.android.kt:141)
at CompositionLocalProvider(CompositionLocal.kt:384)
at <lambda>(Wrapper.android.kt:140)
Bekannte Einschränkungen
Es gibt einige bekannte Probleme mit Stacktrace-Frames:
Stacktraces mit Quellinformationen
Fehlende Zeilennummern (<unknown line>) im ersten Stackframe für Abstürze in der Komposition. Da die Quellinformationen erst nach einem Absturz geprüft werden, können die Daten in der Slot-Tabelle unvollständig sein und die Zeilennummer kann fehlen.
ReusableComposeNode und remember liefern keine Quellinformationen. Daher wird in den Stackframes für diese Funktionen <unknown line> angezeigt.
Stacktraces für Gruppierungsschlüssel
GroupKeys-basierte Stacktraces können nur auf die erste Zeile der @Composable-Funktion verweisen. Sie enthalten auch keine Daten für Funktionen, die keine Gruppe erzeugen, z. B. Inline- oder nicht einheitenbezogene Funktionen.
Abstürze beim Erfassen von Stacktraces
Wenn die Erfassung des Stack-Trace aus irgendeinem Grund abstürzt, wird diese Ausnahme als unterdrückte Ausnahme anstelle von DiagnosticComposeException angehängt.
Melden Sie alle unterdrückten Abstürze oder Inkonsistenzen im Stacktrace in der Compose-Laufzeitkomponente.