التعامل مع تغييرات الإعدادات (original) (raw)

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

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

هذه الأجهزة.

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

إعادة إنشاء الأنشطة

يعيد النظام إنشاء Activity عند حدوث تغيير في الإعدادات. لإجراء ذلك، يُطلِق النظامonDestroy() ويُزيل مثيل Activity الحالي. بعد ذلك، يتم إنشاء مثيل جديد باستخدام onCreate()، ويتم تهيئة مثيل Activity الجديد بالإعدادات الجديدة المعدَّلة. ويعني ذلك أيضًا أنّ النظام يعيد أيضًا إنشاء واجهة المستخدم باستخدام الإعدادات الجديدة.

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

مثال على الأنشطة الترفيهية

لنفترض أنّ TextView يعرض عنوانًا ثابتًا باستخدامandroid:text="@string/title"، كما هو محدّد في ملف XML الخاص بالتنسيق. عند إنشاء العرض، يتم ضبط النص مرة واحدة فقط استنادًا إلى اللغة الحالية. في حال تغيّر اللغة، يعيد النظام إنشاء النشاط. نتيجةً لذلك، يعيد النظام إنشاء طريقة العرض ويُنشئها بالقيمة الصحيحة استنادًا إلى اللغة الجديدة.

تؤدي عملية إعادة الإنشاء أيضًا إلى محو أي حالة محفوظة كحقول فيActivity أو في أي من Fragment أو View أو عناصر أخرى مضمّنة فيه. ويعود سبب ذلك إلى أنّ إعادة إنشاء Activity تؤدي إلى إنشاء مثيل جديد تمامًا من Activityوواجهة المستخدم. بالإضافة إلى ذلك، لم يعُد Activity القديم مرئيًا أو صالحًا، لذا فإنّ أي مراجع متبقية إليه أو إلى الكائنات التي يحتوي عليها قديمة. ويمكن أن تؤدي إلى ظهور أخطاء وتسرُّب للذاكرة وأعطال.

توقعات المستخدمين

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

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

هناك ثلاث طرق أساسية يمكنك اتّباعها للحفاظ على الحالة ذات الصلة من خلالActivity إعادة الإنشاء. يعتمد نوع الحالة التي تريد الحفاظ عليها على نوع العنصر:

للاطّلاع على تفاصيل واجهات برمجة التطبيقات لكلّ من هذه الواجهات، ومعرفة الحالات التي يكون فيها استخدام كلّ منها مناسبًا، اطّلِع على مقالة حفظ حالات واجهة المستخدم.

حظر إعادة إنشاء الأنشطة

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

لإيقاف إعادة إنشاء الأنشطة عند إجراء تغييرات معيّنة على الإعدادات، أضِف نوع الإعدادات إلى android:configChanges في إدخال في ملف AndroidManifest.xml. تظهر القيم المحتمَلة في مستندات السمة android:configChanges.

يوقف رمز البيان التالي إعادة إنشاء Activity لـ MyActivity عند تغيير اتجاه الشاشة وتوفّر لوحة المفاتيح:

<activity
    android:name=".MyActivity"
    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
    android:label="@string/app_name">

تؤدي بعض تغييرات الإعدادات دائمًا إلى إعادة تشغيل النشاط. ولا يمكنك إيقافه. على سبيل المثال، لا يمكنك إيقاف ميزة تغيير الألوان الديناميكيةالتي تم تقديمها في Android 12L (المستوى 32 من واجهة برمجة التطبيقات).

التفاعل مع تغييرات الإعدادات في نظام View

في نظام View، عند حدوث تغيير في الإعدادات أدّى إلى إيقاف إعادة إنشاء Activity، يتلقّى النشاط طلبًا لActivity.onConfigurationChanged(). تتلقّى أيضًا أيّ طرق عرض مرفقة دعوةً لتعديل View.onConfigurationChanged(). بالنسبة إلى تغييرات الضبط التي لم تُضفها إلى android:configChanges، يُعيد النظام إنشاء النشاط كالعادة.

تتلقّى طريقة الاستدعاء onConfigurationChanged() عنصرًاConfiguration يحدّد إعدادات الجهاز الجديدة. اقرأ الحقول في عنصر Configuration لتحديد الإعدادات الجديدة التي تريدها. لإجراء التغييرات اللاحقة، عدِّل الموارد التي تستخدمها في واجهتك. عندما يستدعي النظام هذه الطريقة، يتم تعديل عنصرResources في نشاطك لعرض الموارد استنادًا إلى الإعدادات الجديدة. يتيح لك ذلك إعادة ضبط عناصر واجهة المستخدم بدون أن يعيد النظام بدء نشاطك.

على سبيل المثال، تتحقّق عملية تنفيذ onConfigurationChanged() التالية مما إذا كانت لوحة المفاتيح متاحة:

Kotlin

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)

    // Checks whether a keyboard is available
    if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show()
    } else if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_NO) {
        Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show()
    }
}

Java

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks whether a keyboard is available
    if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show();
    } else if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO){
        Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show();
    }
}

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

الاحتفاظ بالحالة

عند استخدام هذه الطريقة، يجب الاحتفاظ بالحالة أثناء دورة حياة النشاط العادية. ويرجع ذلك إلى الأسباب التالية:

الاستجابة لتغييرات الإعدادات في Jetpack Compose

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

يتوفّر العنصر Configuration في التسلسل الهرمي لواجهة مستخدم "الكتابة" مع تركيبة LocalConfiguration المحلية. عند حدوث تغيير، تتم إعادة تركيب الدوال القابلة للتجميع التي تقرأ من LocalConfiguration.current. للحصول على معلومات عن آلية عمل متغيرات CompositionLocal، اطّلِع على البيانات على النطاق المحلي باستخدام CompositionLocal.

مثال

في المثال التالي، يعرض عنصر قابل للتركيب تاريخًا بتنسيق محدّد. يتفاعل العنصر القابل للتجميع مع تغييرات إعدادات لغة النظام من خلال استدعاءConfigurationCompat.getLocales() باستخدام LocalConfiguration.current.

@Composable
fun DateText(year: Int, dayOfYear: Int) {
    val dateTimeFormatter = DateTimeFormatter.ofPattern(
        "MMM dd",
        ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
    )
    Text(
        dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
    )
}

لتجنُّب إعادة إنشاء Activity عند تغيير اللغة، يجب أن يوقف Activity الذي يستضيف رمز الإنشاء تغييرات إعدادات اللغة. لإجراء ذلك، عليك ضبط android:configChanges على locale|layoutDirection.

تغييرات الإعداد: المفاهيم الرئيسية وأفضل الممارسات

في ما يلي المفاهيم الأساسية التي يجب معرفتها عند العمل على تغييرات الإعدادات:

لتقديم تجربة إيجابية للمستخدم، اتّبِع أفضل الممارسات التالية:

التعامل مع تغييرات الإعدادات المستندة إلى الحجم

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

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

حصر إعادة إنشاء الأنشطة بتغييرات الإعدادات المستندة إلى الحجم

عند إيقاف إعادة إنشاء Activity بسبب تغييرات الضبط المستندة إلى الحجم، لن يعيد النظام إنشاء Activity. بدلاً من ذلك، يتلقّى طلبًا للاتصال بالرقم Activity.onConfigurationChanged(). تتلقّى أيّ مشاهدات مرفقة مكالمة إلىView.onConfigurationChanged().

تكون ميزة إعادة إنشاء Activity غير مفعّلة لتغييرات الضبط المستندة إلى الحجم عندما يكون لديكandroid:configChanges="screenSize|smallestScreenSize|orientation|screenLayout"في ملف البيان.

السماح بإعادة إنشاء النشاط لإجراء تغييرات على الإعدادات المستندة إلى الحجم

في الإصدار 7.0 من نظام التشغيل Android (المستوى 24 من واجهة برمجة التطبيقات) والإصدارات الأحدث، Activityلا يتم إنشاء ملف جديد إلا عند إجراء تغييرات على الإعدادات المستندة إلى الحجم إذا كان تغيير الحجم كبيرًا. عندما لا يعيد النظام إنشاء Activity بسبب عدم كفاية الحجم، قد يستدعي النظامActivity.onConfigurationChanged() وView.onConfigurationChanged() بدلاً من ذلك.

هناك بعض التحذيرات التي يجب مراعاتها في ما يتعلّق بطلبات Activity وViewالمُعاد الاتصال بها عندما لا تتم إعادة إنشاء Activity:

بالنسبة إلى الرمز الذي يعتمد على الاستماع إلى التغيُّرات في الإعدادات المستندة إلى الحجم، ننصحك باستخدام أداة View معView.onConfigurationChanged() تم إلغاء تحديدها بدلاً من الاعتماد على إعادة إنشاء Activity أوActivity.onConfigurationChanged().