إصلاح مشاكل الثبات

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

تفعيل التخطّي القوي

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

راجِع القسم التخطّي القوي للحصول على مزيد من المعلومات.

جعل الصف غير قابل للتغيير

كما يمكنك محاولة جعل فئة غير مستقرة غير قابلة للتغيير تمامًا.

  • غير قابل للتغيير: يشير إلى نوع حيث لا يمكن أبدًا لقيمة أي خصائص التغيير بعد إنشاء مثيل من هذا النوع، وتصبح جميع الطرق شفافة من الناحية المرجعية.
    • يُرجى التأكّد من أنّ سمات الصف هي val وليس var. وأنواع غير قابلة للتغيير.
    • تكون الأنواع الأولية مثل String, Int وFloat غير قابلة للتغيير دائمًا.
    • إذا كان هذا مستحيلاً، فيجب عليك استخدام حالة "Compose" (الإنشاء) من أجل وأي خصائص قابلة للتغيير.
  • ثابت: تشير إلى نوع قابل للتغيير. لا تُستخدم بيئة تشغيل Compose أن تكون على دراية بما إذا كان أي من الملكيات العامة أو أي من الطرق نتائج مختلفة عن استدعاء سابق.

المجموعات غير القابلة للتغيير

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

لحل هذه المشكلة، يمكنك استخدام المجموعات غير القابلة للتغيير. مجمِّع المحتوى في Compose دعم مجموعات Kotlinx غير القابلة للتغيير. هذه تضمن أن تكون المجموعات غير قابلة للتغيير، ويتعامل معها المحول البرمجي في Compose على هذا النحو. لا تزال هذه المكتبة في مرحلة الإصدار الأولي، لذا توقَّع إجراء تغييرات محتملة على واجهة برمجة التطبيقات الخاصة بها.

ضع في اعتبارك مرة أخرى هذه الفئة غير المستقرة من تشخيص استقرار التشخيص دليل:

unstable class Snack {
  
  unstable val tags: Set<String>
  
}

يمكنك جعل tags ثابتة باستخدام مجموعة غير قابلة للتغيير. في الفصل، غيِّر نوع من tags إلى ImmutableSet<String>:

data class Snack{
    
    val tags: ImmutableSet<String> = persistentSetOf()
    
}

وبعد القيام بذلك، تصبح جميع معلمات الفئة غير قابلة للتغيير، يحدد برنامج التحويل البرمجي الفئة على أنها ثابتة.

إضافة تعليقات توضيحية باستخدام Stable أو Immutable

أحد الطرق المحتملة لحل مشكلات الاستقرار هو التعليق التوضيحي على الفئات غير الثابتة مع @Stable أو @Immutable.

إن التعليق التوضيحي على فئة يؤدي إلى إلغاء ما قد يطبقه المحول البرمجي استنتاج المعلومات حول صفك. إنه مشابه لـ !! في لغة Kotlin. يجب أن تكون تقنيًا حذرًا بشأن كيفية استخدام هذه التعليقات التوضيحية. تجاوز سلوك المحول البرمجي إلى أخطاء غير متوقعة، مثل عدم إعادة إنشاء المستند القابل للإنشاء كما تتوقع.

إذا كان من الممكن جعل فئتك ثابتة بدون تعليق توضيحي، يجب عليك والسعي لتحقيق الاستقرار بهذه الطريقة.

يقدم المقتطف التالي مثالاً مصغرًا لفئة بيانات تم التعليق عليها باعتبارها غير قابل للتغيير:

@Immutable
data class Snack(

)

سواء كنت تستخدم التعليق التوضيحي @Immutable أو @Stable، يمكنك استخدام المحول البرمجي للإنشاء. تحدد الفئة Snack على أنها ثابتة.

صفوف بتعليقات توضيحية في المجموعات

يمكنك استخدام دالة قابلة للإنشاء تتضمّن مَعلمة من النوع List<Snack>:

restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
  
  unstable snacks: List<Snack>
  
)

حتى إذا أضفت تعليقات توضيحية إلى Snack باستخدام @Immutable، سيظل بإمكان المحول البرمجي إنشاء علامات المعلمة snacks في HighlightedSnacks على أنها غير مستقرة.

تواجه المعاملات نفس المشكلة التي تواجه الفئات عندما يتعلق الأمر بأنواع المجموعات، يضع المحول البرمجي Compose دائمًا علامة على معلَمة من النوع List كمَعلمة غير ثابتة، حتى عندما تكون مجموعة من الأنواع الثابتة.

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

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

ملف الإعداد

إذا كنت تريد الالتزام بعقد الاستقرار في قاعدة الرموز لديك، فعندئذ يمكنك الاشتراك في اعتبار مجموعات Kotlin مستقرة من خلال إضافة في kotlin.collections.* ملف إعداد الاستقرار:

مجموعة غير قابلة للتغيير

لسلامة وقت التجميع لعدم القدرة على التغيير، يمكنك استخدام مجموعة kotlinx غير قابلة للتغيير، بدلاً من List.

@Composable
private fun HighlightedSnacks(
    
    snacks: ImmutableList<Snack>,
    
)

Wrapper

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

@Immutable
data class SnackCollection(
   val snacks: List<Snack>
)

يمكنك بعد ذلك استخدام هذا كنوع المعلمة في العنصر القابل للإنشاء.

@Composable
private fun HighlightedSnacks(
    index: Int,
    snacks: SnackCollection,
    onSnackClick: (Long) -> Unit,
    modifier: Modifier = Modifier
)

الحل

بعد اتباع أي من هاتين الطريقتين، يحدد الآن المحول البرمجي لإنشاء HighlightedSnacks قابل للتعديل بتنسيقَي skippable وrestartable.

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

أثناء إعادة الإنشاء، يمكن لميزة "إنشاء" تخطّي HighlightedSnacks في حال عدم توفّر تغيرت المدخلات.

ملف إعداد الثبات

بدءًا من Compose Compiler 1.5.5، وهو ملف تهيئة يضم فئات تعتبره مستقرًا يمكن توفيره في وقت التجميع. يتيح هذا التفكير في الصفوف التي لا تتحكّم فيها، مثل صفوف المكتبة العادية مثل LocalDateTime، باعتبارها ثابتة.

ملف الإعداد هو ملف نص عادي يضم فئة واحدة لكل صف. التعليقات ويمكن استخدام أحرف البدل الفردية والمزدوجة. وفي ما يلي مثال على عملية الضبط:

// Consider LocalDateTime stable
java.time.LocalDateTime
// Consider kotlin collections stable
kotlin.collections.*
// Consider my datalayer and all submodules stable
com.datalayer.**
// Consider my generic type stable based off it's first type parameter only
com.example.GenericClass<*,_>

لتفعيل هذه الميزة، مرر مسار ملف الإعداد إلى القائمة "إنشاء" خيارات التجميع.

Groovy

kotlinOptions {
    freeCompilerArgs += [
            "-P",
            "plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=" +
                    project.absolutePath + "/compose_compiler_config.conf"
    ]
}

Kotlin

kotlinOptions {
  freeCompilerArgs += listOf(
      "-P",
      "plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=" +
      "${project.absolutePath}/compose_compiler_config.conf"
  )
}

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

وحدات متعددة

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

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

الحل

لحل هذه المشكلة، يمكنك اتّباع أحد الأساليب التالية:

  1. أضِف الفئات إلى ملف إعداد أداة التجميع.
  2. تفعيل المحول البرمجي للإنشاء في وحدات طبقة البيانات أو وضع علامات على فئاتك مع @Stable أو @Immutable عندما يكون ذلك مناسبًا.
    • يتضمن هذا إضافة تبعية Compose إلى طبقة البيانات الخاصة بك. ومع ذلك، هي فقط التبعية لوقت تشغيل Compose وليس Compose-UI
  3. ضمن وحدة واجهة المستخدم، عليك إحاطة فئات طبقة البيانات في برنامج تضمين خاص بواجهة المستخدم. الصفوف.

تحدث المشكلة نفسها أيضًا عند استخدام مكتبات خارجية إذا لم تستخدم منشئ التجميع.

لا يجب أن تكون كل مادة قابلة للإنشاء قابلة للتخطي

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

هناك العديد من المواقف التي لا تحقق فيها الإعلانات القابلة للتخطي أي فائدة حقيقية. ويمكن أن يؤدي إلى صعوبة صيانته مثلاً:

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

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