Jetpack Compose wykonuje kod w kilku różnych fazach, co powoduje, że niektóre części funkcji @Composable są wykonywane oddzielnie. Awaria w tych fazach może spowodować powstanie śladów stosu, które są trudne do odczytania, co utrudnia wskazanie dokładnej funkcji lub wiersza kodu, który spowodował awarię.
Dodawanie informacji o źródle do śladów stosu
Aby zwiększyć czytelność śladu stosu, interfejs API z możliwością włączenia udostępnia bardziej szczegółowe informacje o lokalizacji awarii, w tym nazwy i lokalizacje elementów kompozycyjnych, co umożliwia:
- Skuteczne identyfikowanie i usuwanie przyczyn awarii
- Izolowanie awarii w celu uzyskania powtarzalnych próbek
- Badanie awarii, w przypadku których wcześniej wyświetlane były tylko wewnętrzne ramki stosu
Środowisko wykonawcze Compose może wykryć miejsce awarii w kompozycji i odtworzyć ślad stosu na podstawie hierarchii @Composable. Zrzut stosu jest dołączany w przypadku awarii w tych miejscach:
- Kompozycja
DisposableEffectiLaunchedEffect(z wyjątkiemonDisposelub anulowania)- Coroutines launched in
rememberCoroutineScope - Mierzenie, rozmieszczanie i rysowanie przejazdów
Aby włączyć tę funkcję, dodaj te wiersze do punktu wejścia aplikacji:
// 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) } }
Najlepiej przeprowadzić tę konfigurację przed utworzeniem jakichkolwiek kompozycji, aby sprawdzić, czy informacje o śladzie stosu są zbierane prawidłowo.
Dostępne są 4 opcje ComposeStackTraceMode:
Auto: zalecana opcja, ponieważ używaGroupKeys, jeśli aplikacja jest zminimalizowana, aNonew przeciwnym razie.GroupKeys: zrzuty stosu są tworzone w przypadku zminimalizowanych aplikacji. Informacje o kluczu grupy są zachowywane nawet po minifikacji i używane razem z plikiem mapowania ProGuard wygenerowanym przez kompilator Compose i R8 do odtworzenia przybliżonej lokalizacji funkcji@Composable. Te ślady stosu są mniej precyzyjne i zoptymalizowane pod kątem unikania dodatkowej pracy w czasie działania. Kompilator Compose obsługuje generowanie dodatkowych map R8 od wersji Kotlin 2.3.0.SourceInformation: przydatne w przypadku wersji niepomniejszonych, zbiera informacje o źródle i dodaje je do zrzutu stosu. Wyniki są dokładniejsze, ale wiążą się ze znacznym kosztem wydajności, podobnym do dołączenia inspektora układu. Są one tworzone z myślą o używaniu w wersjach debugowania aplikacji, aby uzyskiwać dokładne odczyty dotyczące awarii, które wymagają więcej informacji o swojej lokalizacji. Informacje o źródle są usuwane ze zminimalizowanych aplikacji, aby zoptymalizować rozmiar i wydajność plików binarnych.None: nie dodano żadnych dodatkowych szczegółów zrzutu stosu.
Gdy użyjesz opcji SourceInformation, ślad stosu pojawi się na liście pominiętych wyjątków jako DiagnosticComposeException:
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)
Znane ograniczenia
Istnieje kilka znanych problemów z ramkami śladu stosu:
Zrzuty stosu informacji o źródle
Brak numerów wierszy (<unknown line>) w pierwszej ramce stosu w przypadku awarii w kompozycji. Ponieważ introspekcja informacji o źródle następuje po awarii, dane tabeli slotów mogą być niekompletne i nie zawierać numeru wiersza.
ReusableComposeNode i remember nie generują informacji o źródle, więc w ramkach stosu tych funkcji zobaczysz <unknown line>.
Śledzenie stosu kluczy grupy
Śledzenie stosu oparte na GroupKeys może z założenia wskazywać tylko pierwszy wiersz funkcji @Composable. Nie zawierają też danych dotyczących funkcji, które nie tworzą grupy (np. funkcji wbudowanych lub funkcji zwracających wartość inną niż Unit).
Awarie podczas zbierania zrzutów stosu
Jeśli zbieranie zrzutów stosu z jakiegokolwiek powodu ulegnie awarii, wyjątek zostanie dołączony jako wyjątek pominięty zamiast DiagnosticComposeException.
Zgłaszaj wszelkie pominięte awarie lub niespójności śladu stosu do komponentu Compose Runtime.