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

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

أداة فحص التصميم

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

تعداد إعادة الإنشاء والتخطي في عارض التخطيط

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

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

ضبط إعدادات الجهاز

لا يتم تفعيل تقارير برنامج التحويل البرمجي بشكل تلقائي. يمكنك تنشيطها باستخدام علامة برنامج التحويل البرمجي. يختلف الإعداد الدقيق حسب مشروعك، ولكن بالنسبة إلى معظم المشاريع، يمكنك لصق النص البرمجي التالي في ملف build.gradle الجذر.

رائع

subprojects {
  tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
        kotlinOptions {
            if (project.findProperty("composeCompilerReports") == "true") {
                freeCompilerArgs += [
                        "-P",
                        "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
                                project.buildDir.absolutePath + "/compose_compiler"
                ]
            }
            if (project.findProperty("composeCompilerMetrics") == "true") {
                freeCompilerArgs += [
                        "-P",
                        "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
                                project.buildDir.absolutePath + "/compose_compiler"
                ]
            }
        }
    }
}

Kotlin

subprojects {
    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
        kotlinOptions {
            if (project.findProperty("composeCompilerReports") == "true") {
                freeCompilerArgs += listOf(
                    "-P",
                    "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=${project.buildDir.absolutePath}/compose_compiler"
                )
            }
            if (project.findProperty("composeCompilerMetrics") == "true") {
                freeCompilerArgs += listOf(
                    "-P",
                    "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=${project.buildDir.absolutePath}/compose_compiler"
                )
            }
        }
    }
}

تنفيذ المهمة

لتصحيح أخطاء ثبات العناصر القابلة للإنشاء، شغِّل المهمة على النحو التالي:

./gradlew assembleRelease -PcomposeCompilerReports=true

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

تُنتج هذه المهمة ثلاثة ملفات. في ما يلي أمثلة على مخرجات من 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 على أنّه غير ثابت.