تشخيص مشاكل الثبات

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

أداة فحص التنسيق

تتيح لك أداة فحص التنسيق في "استوديو Android" معرفة الدوال المركّبة التي تتم إعادة تكوينها في تطبيقك، كما تعرض عدد المرات التي أعادت فيها Compose تكوين أحد المكوّنات أو تخطّته.

عدد عمليات إعادة الإنشاء وعمليات التخطّي في "أداة فحص التنسيق"

إنشاء تقارير المترجم

يمكن لمترجم Compose عرض نتائج استنتاجه بشأن الثبات لتتمكّن من فحصها. باستخدام هذه النتيجة، يمكنك تحديد الدوال المركّبة التي يمكن تخطّيها وتلك التي لا يمكن تخطّيها. تلخّص الأقسام الفرعية التالية كيفية استخدام هذه التقارير، ولكن للحصول على معلومات أكثر تفصيلاً، يمكنك الاطّلاع على المستندات الفنية.

الإعداد

لا يتم تفعيل تقارير برنامج التجميع في Compose تلقائيًا. يمكنك تفعيلها باستخدام علامة مترجم. يختلف الإعداد الدقيق حسب مشروعك، ولكن بالنسبة إلى المشاريع التي تستخدم المكوّن الإضافي Compose compiler gradle، يمكنك إضافة ما يلي في ملف build.gradle لكل وحدة.

  android { ... }

  composeCompiler {
    reportsDestination = layout.buildDirectory.dir("compose_compiler")
    metricsDestination = layout.buildDirectory.dir("compose_compiler")
  }

سيتم الآن إنشاء تقارير أداة تجميع Compose عند إنشاء مشروعك.

مثال على الناتج

ينتج عن reportsDestination ثلاثة ملفات. في ما يلي أمثلة على النتائج التي تعرضها JetSnack.

  • <modulename>-classes.txt: تقرير عن ثبات الفئات في هذا الوحدة. نموذج
  • <modulename>-composables.txt: تقرير عن إمكانية إعادة تشغيل العناصر القابلة للإنشاء وإمكانية تخطّيها في الوحدة مثال
  • <modulename>-composables.csv:إصدار CSV من تقرير العناصر القابلة للإنشاء يمكنك استيراده إلى جدول بيانات أو معالجته باستخدام نص برمجي. عيّنة

تقرير العناصر القابلة للإنشاء

يقدّم ملف composables.txt تفاصيل كل دالة مركّبة في الوحدة المحدّدة، بما في ذلك ثبات مَعلمات الدوال وما إذا كانت قابلة لإعادة التشغيل أو قابلة للتخطي. في ما يلي مثال افتراضي من JetSnack:

restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection(
  stable snackCollection: SnackCollection
  stable onSnackClick: Function1<Long, Unit>
  stable modifier: Modifier? = @static Companion
  stable index: Int = @static 0
  stable highlight: Boolean = @static true
)

يمكن إعادة تشغيل العنصر المركّب SnackCollection بالكامل، ويمكن تخطّيه، كما أنّه ثابت. ويُفضّل استخدام هذا العنصر بشكل عام، ولكنّه ليس إلزاميًا.

يمكنك بدلاً من ذلك الاطّلاع على مثال آخر.

restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
  stable index: Int
  unstable snacks: List<Snack>
  stable onSnackClick: Function1<Long, Unit>
  stable modifier: Modifier? = @static Companion
)

لا يمكن تخطّي العنصر القابل للإنشاء HighlightedSnacks، إذ لا يتخطّاه Compose أبدًا أثناء إعادة التركيب، حتى إذا لم تتغيّر أيّ من مَعلماته، والسبب في ذلك هو المَعلمة unstable، أي snacks.

تقرير "الصفوف"

يحتوي الملف classes.txt على تقرير مشابه بشأن الفئات في الوحدة النمطية المحدّدة. المقتطف التالي هو الناتج للفئة Snack:

unstable class Snack {
  stable val id: Long
  stable val name: String
  stable val imageUrl: String
  stable val price: Long
  stable val tagline: String
  unstable val tags: Set<String>
  <runtime stability> = Unstable
}

للعلم، إليك تعريف Snack:

data class Snack(
    val id: Long,
    val name: String,
    val imageUrl: String,
    val price: Long,
    val tagline: String = "",
    val tags: Set<String> = emptySet()
)

وضع محرّر Compose علامة غير مستقر على Snack، لأنّ نوع المَعلمة tags هو Set<String>، وهو نوع غير قابل للتغيير، لأنّه ليس MutableSet. ومع ذلك، فإنّ فئات المجموعات العادية، مثل Set وList وMap، هي في النهاية واجهات، وبالتالي قد يظل التنفيذ الأساسي قابلاً للتغيير.

على سبيل المثال، يمكنك كتابة val set: Set<String> = mutableSetOf("foo"). المتغيّر ثابت ونوعه المعلَن غير قابل للتغيير، ولكن تنفيذه لا يزال قابلاً للتغيير. لا يمكن لمترجم Compose التأكّد من عدم قابلية هذه الفئة للتغيير لأنّه يرى النوع المعلَن فقط. لذلك، يتم تصنيف الإصدار tags على أنّه غير ثابت.