Jetpack Compose thực thi mã của bạn qua nhiều giai đoạn khác nhau, khiến một số phần của hàm @Composable được thực thi riêng biệt với nhau. Sự cố trong các giai đoạn này có thể dẫn đến dấu vết ngăn xếp khó giải mã, khiến bạn khó xác định chính xác hàm hoặc dòng mã gây ra sự cố.
Thêm thông tin nguồn vào dấu vết ngăn xếp
Để cải thiện khả năng đọc dấu vết ngăn xếp, một API chọn tham gia sẽ cung cấp thông tin chi tiết hơn về vị trí gặp sự cố, bao gồm cả tên và vị trí của thành phần kết hợp, cho phép bạn:
- Xác định và giải quyết hiệu quả các nguồn gây ra sự cố
- Tách biệt các sự cố để có mẫu có thể tái tạo
- Điều tra các sự cố mà trước đây chỉ cho thấy các khung ngăn xếp nội bộ
Thời gian chạy Compose có thể phát hiện vị trí gặp sự cố trong thành phần và tạo lại dấu vết ngăn xếp dựa trên hệ phân cấp @Composable của bạn. Dấu vết ngăn xếp được thêm vào cho các sự cố trong:
- Bản sáng tác
DisposableEffectvàLaunchedEffect(ngoại trừonDisposehoặc việc huỷ)- Coroutine được khởi chạy trong
rememberCoroutineScope - Đo lường, bố cục và vẽ các đường chuyền
Để bật tính năng này, hãy thêm các dòng sau vào điểm truy cập ứng dụng:
// 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) } }
Tốt nhất là bạn nên thực hiện cấu hình này trước khi tạo bất kỳ thành phần nào để xác minh rằng thông tin dấu vết ngăn xếp được thu thập chính xác.
Có 4 lựa chọn cho ComposeStackTraceMode:
Auto: Lựa chọn nên dùng, vì lựa chọn này sử dụngGroupKeysnếu ứng dụng được rút gọn vàNonenếu không.GroupKeys: Dấu vết ngăn xếp được tạo cho các ứng dụng được rút gọn. Thông tin khoá nhóm được giữ lại ngay cả sau khi rút gọn và được dùng cùng với tệp ánh xạ proguard do trình biên dịch Compose và R8 phát ra để tái tạo vị trí tương đối của các hàm@Composable. Những dấu vết ngăn xếp này ít chính xác hơn và được tối ưu hoá để tránh thực hiện thêm công việc trong thời gian chạy. Trình biên dịch Compose hỗ trợ phát ra các ánh xạ R8 bổ sung kể từ Kotlin 2.3.0.SourceInformation: Hữu ích cho các bản dựng không được rút gọn, thu thập thông tin nguồn và thêm thông tin đó vào dấu vết ngăn xếp. Kết quả chính xác hơn, nhưng sẽ làm giảm hiệu suất đáng kể, tương tự như việc đính kèm Layout Inspector. Các tệp này được tạo để sử dụng trong các phiên bản gỡ lỗi của ứng dụng nhằm nhận được thông tin đọc chính xác về sự cố cần thêm thông tin về vị trí của sự cố. Thông tin nguồn sẽ bị xoá khỏi các ứng dụng được rút gọn để tối ưu hoá kích thước và hiệu suất của tệp nhị phân.None: Không thêm thông tin chi tiết nào khác về dấu vết ngăn xếp.
Khi bạn sử dụng lựa chọn SourceInformation, dấu vết ngăn xếp sẽ xuất hiện dưới dạng DiagnosticComposeException trong danh sách ngoại lệ bị chặn:
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)
Các hạn chế đã biết
Có một số vấn đề đã biết với các khung dấu vết ngăn xếp:
Dấu vết ngăn xếp thông tin nguồn
Thiếu số dòng (<unknown line>) trong khung ngăn xếp đầu tiên cho các sự cố trong thành phần. Vì quá trình tự kiểm tra thông tin nguồn diễn ra sau sự cố, dữ liệu bảng khe cắm có thể chưa đầy đủ và giảm số dòng.
ReusableComposeNode và remember không tạo ra thông tin nguồn, vì vậy bạn sẽ thấy <unknown line> trong các khung ngăn xếp cho những hàm đó.
Dấu vết ngăn xếp khoá nhóm
Theo thiết kế, dấu vết ngăn xếp dựa trên GroupKeys chỉ có thể trỏ đến dòng đầu tiên của hàm @Composable. Chúng cũng không chứa dữ liệu cho bất kỳ hàm nào không tạo ra một nhóm (chẳng hạn như các hàm nội tuyến hoặc không trả về Unit)
Sự cố thu thập dấu vết ngăn xếp
Nếu quá trình thu thập dấu vết ngăn xếp gặp sự cố vì bất kỳ lý do nào, thì ngoại lệ đó sẽ được thêm dưới dạng một ngoại lệ bị chặn thay vì DiagnosticComposeException.
Báo cáo mọi sự cố bị chặn hoặc sự không nhất quán của dấu vết ngăn xếp cho thành phần Compose Runtime.