إذا كنت تواجه مشاكل في الأداء تنتج عن إعادة تركيب غير ضرورية أو مفرطة، ينبغي لك تصحيح الأخطاء في ثبات تطبيقك. ويوضّح هذا الدليل عدة طرق لإجراء ذلك.
أداة فحص التصميم
تتيح لك أداة "فحص التنسيق" في "استوديو 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
على أنّه غير ثابت.