تتبُّع تسلسل استدعاء الدوال البرمجية في Compose

ينفّذ Jetpack Compose الرمز البرمجي في عدة مراحل مختلفة، ما يؤدي إلى تنفيذ بعض أجزاء الدالة @Composable بشكل منفصل عن بعضها البعض. يمكن أن تؤدي الأعطال في هذه المراحل إلى تتبُّع تسلسل استدعاء الدوال البرمجية الذي يصعب فك رموزه، ما يجعل من الصعب تحديد الدالة أو سطر الرمز البرمجي الدقيق الذي تسبب في العطل.

إضافة معلومات المصدر إلى عمليات تتبُّع تسلسل استدعاء الدوال البرمجية

لتحسين إمكانية قراءة تتبُّع تسلسل استدعاء الدوال البرمجية، توفّر واجهة برمجة تطبيقات اختيارية تفاصيل أكثر ثراءً عن موقع التعطُّل، بما في ذلك أسماء الدوال المركّبة ومواقعها الجغرافية، ما يتيح لك:

  • تحديد مصادر الأعطال وحلّها بكفاءة
  • عزل الأعطال للحصول على عيّنات قابلة للتكرار
  • التحقيق في الأعطال التي كانت تعرض في السابق إطارات حزمة التكديس الداخلية فقط

يمكن لبيئة التشغيل في Compose رصد موقع التعطُّل في التركيب وإعادة إنشاء تتبع تسلسل استدعاء الدوال البرمجية استنادًا إلى التسلسل الهرمي لـ @Composable. يتم إلحاق تتبُّع تسلسل استدعاء الدوال البرمجية للأعطال في:

  • مقطوعة موسيقية
  • ‫DisposableEffect وLaunchedEffect (باستثناء 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: يتم إنشاء عمليات تتبُّع تسلسل استدعاء الدوال البرمجية للتطبيقات التي تمت إزالة البيانات غير الضرورية منها. يتم الاحتفاظ بمعلومات مفتاح المجموعة حتى بعد إزالة البيانات غير الضرورية، ويتم استخدامها مع ملف ربط proguard الذي يصدره برنامج تجميع Compose وR8 لإعادة إنشاء موقع تقريبي لدوال @Composable. تكون عمليات تتبُّع تسلسل استدعاء الدوال البرمجية هذه أقل دقة، ويتم تحسينها لتجنُّب تنفيذ مهام إضافية أثناء وقت التشغيل. يتيح برنامج تجميع Compose إصدار عمليات ربط R8 إضافية بدءًا من الإصدار 2.3.0 من Kotlin.
  • ‫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.