สแต็กเทรซใน Compose

Jetpack Compose จะเรียกใช้โค้ดของคุณในหลายเฟสที่แตกต่างกัน ซึ่งทำให้@Composableบางส่วนของฟังก์ชันถูกเรียกใช้แยกจากกัน การขัดข้องในระยะเหล่านี้อาจส่งผลให้เกิดการติดตามสแต็กที่เข้าใจได้ยาก ทำให้ระบุฟังก์ชันหรือบรรทัดของโค้ดที่ทำให้เกิดการขัดข้องได้ยาก

เพิ่มข้อมูลแหล่งที่มาลงใน Stack Trace

API แบบเลือกใช้จะให้รายละเอียดตำแหน่งที่เกิดข้อขัดข้องที่ละเอียดยิ่งขึ้น รวมถึงชื่อและตำแหน่งที่ประกอบได้ เพื่อปรับปรุงความสามารถในการอ่าน Stack Trace ซึ่งช่วยให้คุณทำสิ่งต่อไปนี้ได้

  • ระบุและแก้ไขแหล่งที่มาของการขัดข้องอย่างมีประสิทธิภาพ
  • แยกข้อขัดข้องสำหรับตัวอย่างที่ทำซ้ำได้
  • ตรวจสอบข้อขัดข้องที่ก่อนหน้านี้แสดงเฉพาะเฟรมสแต็กภายใน

รันไทม์ของ Compose สามารถตรวจหาตำแหน่งที่เกิดข้อขัดข้องในการคอมโพสและสร้าง การติดตามสแต็กขึ้นใหม่โดยอิงตามลำดับชั้นของ @Composable ระบบจะต่อท้ายสแต็กเทรซ สำหรับข้อขัดข้องใน

  • การเรียบเรียง
  • DisposableEffect และ LaunchedEffect (ยกเว้น onDispose หรือ การยกเลิก)
  • เปิดตัว Coroutines ใน 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)
    }
}

เราขอแนะนำให้ทำการกำหนดค่านี้ก่อนสร้างคอมโพสิตเพื่อยืนยัน ว่าระบบรวบรวมข้อมูล Stack Trace ได้อย่างถูกต้อง

ComposeStackTraceMode มี 4 ตัวเลือก ดังนี้

  • Auto: ตัวเลือกที่แนะนำเนื่องจากใช้ GroupKeys หากแอปได้รับการลดขนาด และใช้ None ในกรณีอื่นๆ
  • GroupKeys: ระบบจะสร้างสแต็กเทรซสำหรับ แอปที่ย่อขนาด ระบบจะเก็บข้อมูลคีย์กลุ่มไว้แม้หลังจากลดขนาดแล้ว และใช้ร่วมกับไฟล์การแมป ProGuard ที่ปล่อยออกมาโดยคอมไพเลอร์ Compose และ R8 เพื่อสร้างตำแหน่งคร่าวๆ ของฟังก์ชัน @Composable สแต็กเทรซเหล่านี้มีความแม่นยำน้อยกว่า และได้รับการเพิ่มประสิทธิภาพเพื่อหลีกเลี่ยงการทำงานเพิ่มเติมในรันไทม์ คอมไพเลอร์ Compose รองรับการปล่อยการแมป R8 เพิ่มเติมตั้งแต่ Kotlin 2.3.0 เป็นต้นไป
  • 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)

ข้อจำกัดที่ทราบ

ปัญหาที่ทราบเกี่ยวกับเฟรมของ Stack Trace มีดังนี้

สแต็กเทรซของข้อมูลแหล่งที่มา

ไม่มีหมายเลขบรรทัด (<unknown line>) ในเฟรมสแต็กแรกสำหรับการขัดข้องใน องค์ประกอบ เนื่องจากการตรวจสอบข้อมูลแหล่งที่มาเกิดขึ้นหลังจากเกิดข้อขัดข้อง ข้อมูลตารางช่องจึงอาจไม่สมบูรณ์และหมายเลขบรรทัดอาจหายไป ReusableComposeNode และ remember ไม่สร้างข้อมูลแหล่งที่มา คุณจึงเห็น <unknown line> ในเฟรมสแต็กสำหรับฟังก์ชันเหล่านั้น

สแต็กเทรซของคีย์กลุ่ม

GroupKeysสแต็กเทรซที่อิงตามสามารถชี้ไปยังบรรทัดแรกของฟังก์ชัน @Composableได้เท่านั้นตามการออกแบบ นอกจากนี้ ยังไม่มีข้อมูลสำหรับฟังก์ชันที่ไม่ได้สร้างกลุ่ม (เช่น ฟังก์ชันที่แสดงผลแบบอินไลน์หรือแบบไม่ใช่ Unit)

ข้อขัดข้องในการรวบรวมสแต็กเทรซ

หากการรวบรวมสแต็กเทรซขัดข้องไม่ว่าด้วยเหตุผลใดก็ตาม ระบบจะผนวกข้อยกเว้นนั้น เป็นข้อยกเว้นที่ถูกระงับแทน DiagnosticComposeException

รายงานข้อขัดข้องที่ถูกระงับหรือความไม่สอดคล้องกันของ Stack Trace ไปยังคอมโพเนนต์รันไทม์ของ Compose