وضع التخطي القوي

"التخطّي القوي" هو وضع متوفّر في "مجمّع الإنشاء". عند تفعيل هذا الخيار، يؤدي ذلك إلى تغيير سلوك المُجمِّع بطريقتَين:

  • تصبح العناصر القابلة للتجميع التي تحتوي على مَعلمات غير ثابتة قابلة للتخطّي.
  • يتم تذكُّر صور Lambda التي تحتوي على صور غير مستقرة

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

لتفعيل التخطّي القوي في وحدة Gradle في إصدار سابق، عليك تضمين الخيار التالي في كتلة composeCompiler من إعدادات Gradle:

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

إمكانية التخطّي عند الإنشاء

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

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

الحالات التي يجب فيها التخطّي

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

  • تتم مقارنة المَعلمات غير الثابتة باستخدام تساوي المثيل (===).
  • تتم مقارنة المَعلمات الثابتة باستخدام تساوي الكائنات (Object.equals()).

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

قد تحتاج إلى إيقاف ميزة "التخطّي السريع" في المحتوى القابل للتجميع. وهذا يعني أنّك قد تحتاج إلى ملف مؤلف قابل لإعادة التشغيل ولكن لا يمكن تخطّيه. في هذه الحالة، يمكنك استخدام تعليق @NonSkippableComposable التوضيحي.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

إضافة تعليقات توضيحية إلى الفئات كثابتة

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

تذكارات Lambda

يتيح وضع التخطي القوي أيضًا المزيد من تخزين المراجع للوظائف lambda داخل العناصر القابلة للتجميع. عند تفعيل ميزة "التخطّي القوي"، سيتم تلقائيًا تذكُّر كل دالة LAMBDA داخل دالة قابلة للتجميع.

أمثلة

لحفظ دوال lambdas داخل العناصر القابلة للإنشاء عند استخدام التخطّي القوي، يلتف المحول البرمجي lambda باستدعاء remember. ويتمّ استخدام ملف السجلّ مع عمليات تسجيل دالة lambda.

لنفترض أنّ لديك دالة lambda كما هو موضّح في المثال التالي:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

عند تفعيل التخطّي القوي، يحفظ المحول البرمجي lambda من خلال التفافه في استدعاء remember:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

تلتزم المفاتيح بقواعد المقارنة نفسها التي تلتزم بها الدوالّ القابلة للتجميع. تقارن بيئة التشغيل المفاتيح غير المستقرة باستخدام مساواة العنصر. ويقارن المفاتيح الثابتة باستخدام تكافؤ العناصر.

الحفظ المؤقت وإعادة التركيب

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

تجنَّب ميزة "تذكير".

إذا كان لديك lambda لا تريد تذكّره، استخدم التعليق التوضيحي @DontMemoize.

val lambda = @DontMemoize {
    ...
}

حجم حزمة APK

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

أدى تفعيل التخطّي القوي في تطبيق Now In Android إلى زيادة حجم ملف APK بمقدار 4 كيلوبايت. يعتمد الفارق في الحجم إلى حد كبير على عدد العناصر القابلة للإنشاء غير القابلة للتخطي سابقًا والتي كانت متوفّرة في التطبيق المحدّد، ولكن يجب أن تكون طفيفة نسبيًا.