تتبُّع تسلسل استدعاء الدوال البرمجية في 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 بحسب التصميم. ولا تحتوي أيضًا على أي بيانات لأي دوال لا تنتج مجموعة (مثل الدوال المضمّنة أو الدوال التي لا تعرض قيمة من النوع Unit).

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

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

يُرجى الإبلاغ عن أي أعطال تم إخفاؤها أو حالات عدم اتساق في تتبُّع تسلسل استدعاء الدوال البرمجية إلى مكوّن Compose Runtime.