Compose 中的堆疊追蹤

Jetpack Compose 會在多個不同階段執行程式碼,因此 @Composable 函式的某些部分會分開執行。如果在這兩個階段發生當機,堆疊追蹤可能會難以解讀,導致難以找出造成當機的確切函式或程式碼行。

將來源資訊新增至堆疊追蹤

為提高堆疊追蹤的可讀性,選擇加入 API 可提供更豐富的當機位置詳細資料,包括可組合函式名稱和位置,讓您能夠:

  • 有效找出並解決當機來源
  • 找出可重現當機情形的樣本
  • 調查先前只顯示內部堆疊框架的當機問題

Compose 執行階段可偵測組合中的當機位置,並根據 @Composable 階層重新建構堆疊追蹤。系統會為下列當機情況附加堆疊追蹤:

  • 樂曲
  • DisposableEffect和LaunchedEffect (onDispose或取消除外)
  • 在 rememberCoroutineScope 中啟動的協同程式
  • 測量、版面配置和繪製傳遞

如要啟用這項功能,請在應用程式進入點加入下列程式碼:

// 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)
    }
}

建議您在建立任何組合之前完成這項設定,確認堆疊追蹤資訊是否正確收集。

ComposeStackTraceMode 有四個選項:

  • Auto:建議選項,因為如果應用程式經過壓縮,系統會使用 GroupKeys,否則會使用 None。
  • GroupKeys:系統會為經過壓縮的應用程式建立堆疊追蹤。即使經過壓縮,系統仍會保留群組金鑰資訊,並與 Compose 編譯器和 R8 發出的 ProGuard 對應檔案搭配使用,以重建 @Composable 函式的大致位置。這些堆疊追蹤較不精確,且經過最佳化,可避免在執行階段執行額外工作。Compose 編譯器支援從 Kotlin 2.3.0 開始發出額外的 R8 對應。
  • SourceInformation:適用於未壓縮的版本,可收集來源資訊並新增至堆疊追蹤。結果會更準確,但會產生與附加版面配置檢查器類似的顯著效能成本。這類檔案用於應用程式的偵錯版本,可準確讀取當機事件,並提供更多相關位置資訊。來源資訊會從縮減的應用程式中移除,以最佳化二進位檔大小和效能。
  • None:未新增額外的堆疊追蹤詳細資料。

使用 SourceInformation 選項時,堆疊追蹤會顯示為抑制例外狀況清單中的 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)

已知限制

堆疊追蹤框架有幾個已知問題:

來源資訊堆疊追蹤

組合中當機的第一個堆疊框架缺少行號 (<unknown line>)。由於來源資訊內省是在當機後進行,因此運算單元資料表資料可能不完整,且會捨棄行號。ReusableComposeNode 和 remember 不會產生來源資訊,因此您會在這些函式的堆疊框架中看到 <unknown line>。

群組金鑰堆疊追蹤

根據設計,GroupKeys 堆疊追蹤只能指向 @Composable 函式的第一行。此外,也不會包含任何不產生群組的函式資料 (例如內嵌或非 Unit 傳回函式)。

堆疊追蹤收集當機

如果堆疊追蹤收集因任何原因而當機,該例外狀況會附加為隱藏的例外狀況,而不是 DiagnosticComposeException。

向 Compose 執行階段元件回報任何隱藏的當機或堆疊追蹤不一致情形。