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

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

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

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

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

รันไทม์ของ 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)
    }
}

คุณควรกำหนดค่านี้ก่อนสร้าง Composition เพื่อยืนยันว่าระบบรวบรวมข้อมูลสแต็กเทรซอย่างถูกต้อง

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)

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

ปัญหาที่ทราบเกี่ยวกับเฟรมสแต็กเทรซมีดังนี้

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

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

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

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

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

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

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