التعامل مع التغييرات في الإعدادات

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

  • حجم عرض التطبيق
  • اتجاه الشاشة
  • حجم الخط وسُمكه
  • اللغة
  • الوضع الداكن مقابل الوضع الفاتح
  • توفُّر لوحة المفاتيح

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

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

التسلية في الأنشطة

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

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

مثال للترفيه

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

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

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

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

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

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

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

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

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

فرض قيود على الأنشطة الترفيهية

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

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

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

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

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

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

في نظام 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 في التدرج الهرمي لواجهة مستخدم "Compose" مع مكان المقطوعة الموسيقية LocalConfiguration على الجهاز. كلما تغير، إعادة تركيب الدوال القابلة للإنشاء التي تقرأها من LocalConfiguration.current. بالنسبة معلومات حول آلية عمل التركيبة المحلية، راجِع المقالة نطاق محلي. باستخدام ChocolateLocal.

مثال

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

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

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

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

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

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

فرض قيود على إعادة إنشاء الأنشطة لتغييرات الإعدادات المستندة إلى الحجم

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

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

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

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

عليك الانتباه إلى بعض التنبيهات بشأن "Activity" و"View". عمليات الاستدعاء عند عدم إعادة إنشاء Activity:

  • في إصدارات Android 11 (المستوى 30 لواجهة برمجة التطبيقات) إلى Android 13 (المستوى 33 لواجهة برمجة التطبيقات)، لم يتم استدعاء "Activity.onConfigurationChanged()".
  • هناك مشكلة معروفة تؤدي إلى عدم ظهور View.onConfigurationChanged() يتم استدعاؤها في بعض الحالات في Android 12L (المستوى 32 لواجهة برمجة التطبيقات) والإصدارات الأقدم من Android 13 (المستوى 33) لمزيد من المعلومات، يُرجى الاطّلاع على هذه المشكلة العلنية. وقد تمت معالجة هذه المشكلة في الإصدارات اللاحقة من نظام التشغيل Android 13 وAndroid 14.

للرموز البرمجية التي تعتمد على الاستماع إلى الإعدادات المستندة إلى الحجم تغييرات، ننصح باستخدام أداة مساعدة View ذات قيمة View.onConfigurationChanged() بدلاً من الاعتماد على Activity أو Activity.onConfigurationChanged()