جارٍ حفظ الحالة مع الأجزاء

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

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

  • المتغيرات: المتغيرات المحلية في الجزء.
  • حالة العرض: أي بيانات مملوكة لملف شخصي واحد أو أكثر في الجزء.
  • SaveState: البيانات المضمّنة في مثيل الجزء هذا والتي يجب حفظها في onSaveInstanceState().
  • UnConfig: هي بيانات يتم سحبها من مصدر خارجي، مثل خادم أو مستودع محلي، أو البيانات التي ينشئها المستخدم والتي يتم إرسالها إلى خادم بعد إتمامها.

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

العملية المُتغيّرات حالة المشاهدة SaveState (حالة الحفظ) غير تهيئة
تمت الإضافة إلى الحزمة السابقة x
تغيير الضبط x
وفيات أو ترفيه x ✓*
لم تتم إضافة المستخدم إلى الحزمة التي تمت إزالتها. x x x x
انتهى المضيف x x x x

* يمكن الاحتفاظ بالحالة غير المضبوطة خلال مرحلة إيقاف العملية باستخدام وحدة الحالة المحفوظة لـ ViewModel.

الجدول 1: العمليات المتنوّعة التي تؤدّي إلى تدمير الأجزاء وآثارها على أنواع الحالات المختلفة

لنلقِ نظرة على مثال محدد. فكِّر في شاشة تنشئ سلسلة عشوائية، وتعرضها في TextView، وتوفّر خيارًا لتعديل السلسلة قبل إرسالها إلى صديق:

تطبيق منشئ نصوص عشوائي يوضّح أنواعًا مختلفة من الحالات
الشكل 1. هو تطبيق لإنشاء نصوص عشوائية يوضّح أنواعًا مختلفة من الحالات.

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

البيانات Type نوع الولاية الوصف
seed Long غير تهيئة يتم استخدام البذرة لتوليد عمل خيري جديد عشوائيًا. يتم إنشاؤه عند إنشاء ViewModel.
randomGoodDeed String SaveState + المتغيّر يتم إنشاؤه عند إنشاء الجزء لأول مرة. يتم حفظ randomGoodDeed لضمان أن يرى المستخدمون العمل الصالح العشوائي نفسه حتى بعد وفاة العملية أو إعادة تنظيمها.
isEditing Boolean SaveState + المتغيّر تم ضبط العلامة المنطقية على true عندما يبدأ المستخدم في التعديل. يتم حفظ isEditing لضمان أن يظل جزء التعديل على الشاشة مرئيًا عند إعادة إنشاء الجزء.
النص المعدَّل Editable حالة المشاهدة (مملوكة من قِبل "EditText") النص المعدَّل في عرض EditText. تحفظ طريقة عرض EditText هذا النص لضمان عدم فقدان التغييرات التي يجريها المستخدم قيد التقدّم.

الجدول 2: يذكر أن تطبيق إنشاء النص العشوائي يجب أن يديره.

توضّح الأقسام التالية طريقة إدارة حالة بياناتك بشكل صحيح من خلال عمليات تدميرية.

عرض الحالة

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

على سبيل المثال، في السيناريو السابق، يتم الاحتفاظ بالسلسلة المعدّلة في EditText. يعرف EditText قيمة النص الذي يعرضه، بالإضافة إلى التفاصيل الأخرى، مثل بداية ونهاية أي نص محدد.

تحتاج طريقة العرض إلى معرّف للاحتفاظ بحالتها. ويجب أن يكون رقم التعريف هذا فريدًا في الجزء والعرض الهرمي لطريقة العرض. لا يمكن للفيديوهات التي لا تتضمّن معرّفًا الاحتفاظ بحالتها.

<EditText
    android:id="@+id/good_deed_edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

كما هو مذكور في الجدول 1، تحفظ طرق العرض ViewState وتستعيدها من خلال جميع العمليات التي لا تزيل الجزء أو تدمر المضيف.

SavedState

يكون الجزء مسؤولًا عن إدارة كميات صغيرة من الحالة الديناميكية التي تُعد جزءًا لا يتجزأ من طريقة عمل الجزء. يمكنك الاحتفاظ بالبيانات المتسلسلة بسهولة باستخدام Fragment.onSaveInstanceState(Bundle). وعلى غرار Activity.onSaveInstanceState(Bundle)، يتم الاحتفاظ بالبيانات التي تدرجها في الحزمة من خلال التغييرات في الإعدادات ومعالجة إيقاف البيانات وإعادة الترفيه، وتكون متاحة في طرق onCreate(Bundle) وonCreateView(LayoutInflater, ViewGroup, Bundle) وonViewCreated(View, Bundle) للجزء الخاص بك.

استكمالاً للمثال السابق، تشير السمة randomGoodDeed إلى الفعل الذي يتم عرضه للمستخدم، في حين أنّ السمة isEditing هي علامة لتحديد ما إذا كان الجزء يعرض علامة EditText أو يخفيها. يجب الاحتفاظ بهذه الحالة المحفوظة باستخدام onSaveInstanceState(Bundle)، كما هو موضَّح في المثال التالي:

Kotlin

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean(IS_EDITING_KEY, isEditing)
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed)
}

Java

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(IS_EDITING_KEY, isEditing);
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed);
}

لاستعادة الحالة في onCreate(Bundle)، يتم استرداد القيمة المخزَّنة من الحزمة:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false)
    randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY)
            ?: viewModel.generateRandomGoodDeed()
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false);
        randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY);
    } else {
        randomGoodDeed = viewModel.generateRandomGoodDeed();
    }
}

كما ورد في الجدول 1، لاحظ أنه يتم الاحتفاظ بالمتغيرات عند وضع الجزء على الحزمة الخلفية. إن معاملتها على أنها حالة محفوظة تضمن استمرارها خلال جميع العمليات المدمرة.

غير تهيئة

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

Kotlin

public class RandomGoodDeedViewModel : ViewModel() {
    private val seed = ... // Generate the seed

    private fun generateRandomGoodDeed(): String {
        val goodDeed = ... // Generate a random good deed using the seed
        return goodDeed
    }
}

Java

public class RandomGoodDeedViewModel extends ViewModel {
    private Long seed = ... // Generate the seed

    private String generateRandomGoodDeed() {
        String goodDeed = ... // Generate a random good deed using the seed
        return goodDeed;
    }
}

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

مراجع إضافية

لمزيد من المعلومات حول إدارة حالة التجزئة، راجع الموارد الإضافية التالية.

الدروس التطبيقية حول الترميز

الأدلّة