Pelacakan tumpukan di Compose

Jetpack Compose mengeksekusi kode Anda dalam beberapa fase berbeda, yang menyebabkan beberapa bagian fungsi @Composable dieksekusi secara terpisah satu sama lain. Error dalam fase ini dapat menghasilkan pelacakan tumpukan yang sulit diuraikan, sehingga sulit untuk menentukan fungsi atau baris kode yang tepat yang menyebabkan error.

Menambahkan info sumber ke stack trace

Untuk meningkatkan keterbacaan stack trace, API keikutsertaan memberikan detail lokasi error yang lebih lengkap, termasuk nama dan lokasi composable, sehingga Anda dapat:

  • Mengidentifikasi dan menyelesaikan sumber error secara efisien
  • Mengisolasi error untuk sampel yang dapat direproduksi
  • Menyelidiki error yang sebelumnya hanya menampilkan frame stack internal

Runtime Compose dapat mendeteksi lokasi error dalam komposisi dan merekonstruksi stack trace berdasarkan hierarki @Composable Anda. Pelacakan tumpukan ditambahkan untuk error di:

  • Komposisi
  • DisposableEffect dan LaunchedEffect (kecuali untuk onDispose atau pembatalan)
  • Coroutine yang diluncurkan di rememberCoroutineScope
  • Pengukuran, tata letak, dan penerusan gambar

Untuk mengaktifkan fitur ini, tambahkan baris berikut ke titik entri aplikasi:

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

Idealnya, lakukan konfigurasi ini sebelum membuat komposisi apa pun untuk memverifikasi bahwa informasi stack trace dikumpulkan dengan benar.

Ada empat opsi untuk ComposeStackTraceMode:

  • Auto: Opsi yang direkomendasikan, karena menggunakan GroupKeys jika aplikasi diminifikasi dan None jika tidak.
  • GroupKeys: Stack trace dibuat untuk aplikasi yang diminifikasi. Informasi kunci grup dipertahankan bahkan setelah minifikasi dan digunakan bersama dengan file pemetaan proguard yang dikeluarkan oleh compiler Compose dan R8 untuk merekonstruksi perkiraan lokasi fungsi @Composable. Rekaman aktivitas ini kurang akurat, dan dioptimalkan untuk menghindari pekerjaan tambahan saat runtime. Compiler Compose mendukung emisi pemetaan R8 tambahan mulai dari Kotlin 2.3.0.
  • SourceInformation: Berguna untuk build yang tidak diminifikasi, mengumpulkan informasi sumber, dan menambahkannya ke stack trace. Hasilnya lebih akurat, tetapi menimbulkan biaya performa yang signifikan yang mirip dengan melampirkan Layout Inspector. File ini dibuat untuk digunakan dalam versi debug aplikasi guna mendapatkan pembacaan yang akurat tentang error yang memerlukan informasi lebih lanjut tentang lokasinya. Informasi sumber dihapus dari aplikasi yang diminifikasi untuk mengoptimalkan ukuran dan performa biner.
  • None: Tidak ada detail stack trace tambahan yang ditambahkan.

Saat menggunakan opsi SourceInformation, stack trace akan muncul sebagai DiagnosticComposeException dalam daftar pengecualian yang disembunyikan:

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)

Batasan umum

Ada beberapa masalah umum terkait frame stack trace:

Pelacakan tumpukan informasi sumber

Nomor baris (<unknown line>) tidak ada dalam frame stack pertama untuk error dalam komposisi. Karena introspeksi informasi sumber terjadi setelah error, data tabel slot dapat tidak lengkap dan menghapus nomor baris. ReusableComposeNode dan remember tidak menghasilkan informasi sumber, jadi Anda akan melihat <unknown line> di frame stack untuk fungsi tersebut.

Stack trace kunci grup

Stack trace berbasis GroupKeys hanya dapat mengarah ke baris pertama fungsi @Composable sesuai desain. Grup juga tidak berisi data apa pun untuk fungsi apa pun yang tidak menghasilkan grup (seperti fungsi inline atau non-Unit yang menampilkan fungsi)

Error pengumpulan stack trace

Jika pengumpulan stack trace error karena alasan apa pun, pengecualian tersebut akan ditambahkan sebagai pengecualian yang disembunyikan, bukan DiagnosticComposeException.

Laporkan setiap error yang disembunyikan atau inkonsistensi stack trace ke komponen Runtime Compose.