Compose 中的堆疊追蹤

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

在堆疊追蹤中新增來源資訊

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

  • 有效找出並解決當機來源
  • 針對可重現的樣本隔離當機問題
  • 調查先前只顯示內部堆疊影格的當機問題

Compose 執行階段可以偵測組合中的當機位置,並根據 @Composable 階層重建堆疊追蹤。堆疊追蹤會附加至下列當機事件:

  • 樂曲
  • DisposableEffectLaunchedEffect (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 函式的大致位置。這些堆疊追蹤記錄的精確度較低,且經過最佳化,可避免在執行階段執行額外工作。從 Kotlin 2.3.0 開始,Compose 編譯器支援發出額外的 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>)。由於來源資訊內省作業是在當機後進行,因此可能導致 slot 資料表資料不完整,並捨棄行號。ReusableComposeNoderemember 不會產生來源資訊,因此您會在這些函式的堆疊框架中看到 <unknown line>

群組索引鍵堆疊追蹤

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

收集堆疊追蹤時發生當機

如果堆疊追蹤收集作業因任何原因而當機,系統會將該例外狀況附加為遭抑制的例外狀況,而非 DiagnosticComposeException

請向 Compose Runtime 元件回報任何遭抑制的當機或堆疊追蹤不一致情形。