يمكن أن تؤثّر عمليات نظام Android المختلفة في حالة المقتطف. لضمان حفظ حالة المستخدم، يحفظ إطار عمل Android تلقائيًا المقاطع ومجموعة الفواصل في الخلفية ويعيدها. لذلك، عليك التأكّد من حفظ أي بيانات في المقتطف واستعادتها أيضًا.
يوضّح الجدول التالي العمليات التي تؤدي إلى فقدان العنصر المجزّأ لحالة، بالإضافة إلى ما إذا كانت الأنواع المختلفة للحالة تستمر خلال تلك التغييرات. في ما يلي أنواع الحالات المذكورة في الجدول:
- المتغيّرات: المتغيّرات المحلية في المقتطف
- حالة العرض: أي بيانات تملكها طريقة عرض واحدة أو أكثر في المقتطف
- SavedState: بيانات متأصلة في مثيل المقتطف هذا والتي يجب حفظها
في
onSaveInstanceState()
- NonConfig: البيانات التي يتمّ استردادها من مصدر خارجي، مثل خادم أو مستودع محلي، أو البيانات التي أنشأها المستخدم والتي يتمّ إرسالها إلى خادم بعد تأكيدها
غالبًا ما يتم التعامل مع المتغيّرات بالطريقة نفسها المتّبعة مع SavedState، إلا أنّ الجدول التالي يميّز بينهما لتوضيح تأثير العمليات المختلفة في كلٍّ منها.
العملية | المتغيّرات | عرض الحالة | SavedState | عدم ضبط |
---|---|---|---|---|
تمت الإضافة إلى الحزمة الخلفية | ✓ | ✓ | x | ✓ |
تغيير الإعدادات | x | ✓ | ✓ | ✓ |
إيقاف العملية نهائيًا/إعادة إنشائها | x | ✓ | ✓ | ✓* |
تمت إزالة الملف بدون إضافته إلى الحزمة الخلفية | x | x | x | x |
انتهى المضيف | x | x | x | x |
* يمكن الاحتفاظ بحالة NonConfig على الرغم من إنهاء العملية باستخدام وحدة الحالة المحفوظة لـ ViewModel.
الجدول 1: العمليات المختلفة التي تؤدي إلى إتلاف الأجزاء والتأثيرات التي تحدثها في أنواع الحالات المختلفة
لنلقِ نظرة على مثال محدّد. لنفترض أنّ هناك شاشة تنشئ سلسلة
عشوائية وتعرضها في TextView
، وتوفر خيارًا لتعديل
السلسلة قبل إرسالها إلى صديق:
في هذا المثال، نفترض أنّه بعد أن يضغط المستخدم على زر التعديل، يعرض
التطبيق طريقة عرض EditText
التي يمكن للمستخدم من خلالها تعديل الرسالة. إذا
نقر المستخدم على إلغاء، من المفترض أن يتم محو طريقة العرض EditText
وضبط مستوى ظهورها علىView.GONE
. قد تتطلّب شاشة مماثلة إدارة أربعة عناصر من البيانات لضمان تجربة
سلسة:
البيانات | النوع | نوع الولاية | الوصف |
---|---|---|---|
seed |
Long |
NonConfig | قيمة الإدخال العشوائية تُستخدَم لإنشاء عمل صالح جديد بشكل عشوائي. يتم إنشاؤه عند
إنشاء ViewModel . |
randomGoodDeed |
String |
SavedState + متغيّر | يتم إنشاؤه عند إنشاء الجزء لأول مرة.
يتم حفظ السمة randomGoodDeed لضمان أن يرى المستخدمون
العمل الصالح العشوائي نفسه حتى بعد انتهاء العملية
وإعادة الإنشاء. |
isEditing |
Boolean |
SavedState + متغيّر | تم ضبط العلامة المنطقية على 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، يُرجى العلم أنّه يتم الاحتفاظ بالمتغيّرات عند وضع ال fragment في الحزمة الخلفية. ويضمن التعامل معها كحالة محفوظة باستمراريتها في جميع العمليات المدمرة.
عدم ضبط
يجب وضع بيانات NonConfig خارج المقتطف، مثل
ViewModel
. في المثال السابق
أعلاه، يتم إنشاء seed
(حالة NonConfig) في 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
بالحفاظ على الحالة البسيطة من خلال
وفاة العملية وإعادة إنشائها.
مصادر إضافية
لمزيد من المعلومات عن إدارة حالة المقتطف، يُرجى الاطّلاع على المراجع التالية الإضافية.
الدروس التطبيقية حول الترميز
- الدرس التطبيقي حول العناصر الواعية بمراحل النشاط