عملیات مختلف سیستم Android میتواند بر وضعیت قطعه شما تأثیر بگذارد. برای اطمینان از ذخیره شدن وضعیت کاربر، چارچوب Android بهطور خودکار تکهها و پشته قبلیها را ذخیره و بازیابی میکند. بنابراین، باید مطمئن شوید که هر دادهای در قطعه شما نیز ذخیره و بازیابی میشود.
جدول زیر عملیاتی را که باعث میشود قطعه شما وضعیت خود را ازدست بدهد، بههمراه اینکه آیا انواع مختلف وضعیت درطول آن تغییرات باقی میمانند یا نه، نشان میدهد. انواع وضعیت ذکرشده در جدول بهشرح زیر است:
- متغیرها: متغیرهای محلی در قطعه.
- وضعیت نما: هر دادهای که متعلق به یک یا چند نما در قطعه باشد.
- SavedState: دادههای ذاتی این نمونه قطعه که باید در
onSaveInstanceState()ذخیره شود. - NonConfig: دادههای استخراجشده از منبع خارجی، مثل سرور یا مخزن محلی، یا دادههای ایجادشده توسط کاربر که پساز تأیید به سرور ارسال میشود.
اغلب با متغیرها مانند SavedState رفتار میشود، اما جدول زیر تفاوت بین این دو را نشان میدهد تا تأثیر عملیات مختلف بر هرکدام را نشان دهد.
| عملیات | متغیرها | مشاهده ایالت | SavedState | NonConfig |
|---|---|---|---|---|
| به پشته قبلیها اضافه شد | ✓ | ✓ | x | ✓ |
| تغییر پیکربندی | x | ✓ | ✓ | ✓ |
| مرگ/بازآفرینی پردازش | x | ✓ | ✓ | ✓* |
| برداشتهشده به پشته قبلیها اضافه نشد | x | x | x | x |
| میزبان تمام شد | x | x | x | x |
* NonConfig state can be retained across process death using the Saved State module for ViewModel.
جدول ۱: عملیاتهای مخرب مختلف قطعه و تأثیراتی که بر انواع مختلف وضعیت دارند.
بیایید به یک مثال خاص نگاه کنیم. صفحهای را درنظر بگیرید که رشتهای تصادفی تولید میکند، آن را در TextView نمایش میدهد، و گزینهای برای ویرایش رشته قبلاز ارسال آن به دوست ارائه میدهد:
برای این مثال، فرض کنید که وقتی کاربر دکمه ویرایش را فشار میدهد،
برنامه نمای EditText را نمایش میدهد که در آن کاربر میتواند پیام را ویرایش کند. اگر
کاربر روی لغو کلیک کند، نمای EditText باید پاک شود و
رؤیتپذیری آن روی View.GONE تنظیم شود. چنین صفحهای ممکن است برای اطمینان از تجربه یکپارچه، نیاز به مدیریت چهار بخش داده داشته باشد:
| داده | نوع | نوع ایالت | شرح |
|---|---|---|---|
seed |
Long |
NonConfig | بذر استفادهشده برای تولید تصادفی کار خوب جدید. وقتی ViewModel ایجاد میشود، تولید میشود. |
randomGoodDeed |
String |
SavedState + Variable | وقتی قطعه برای اولینبار ایجاد میشود، تولید میشود.
randomGoodDeed ذخیره میشود تا اطمینان حاصل شود که کاربران حتی پساز مرگ پردازش و بازآفرینی، همان کار خوب تصادفی را میبینند. |
isEditing |
Boolean |
SavedState + Variable | وقتی کاربر ویرایش را شروع میکند، پرچم بولی روی true تنظیم میشود.
isEditing ذخیره میشود تا اطمینان حاصل شود که بخش ویرایش
صفحه هنگام بازسازی قطعه قابلمشاهده باقی میماند. |
| نوشتار ویرایششده | Editable |
مشاهده وضعیت (متعلق به EditText) |
نوشتار ویرایششده در نمای EditText.
نمای EditText این نوشتار را ذخیره میکند تا مطمئن شود تغییرات درحال انجام کاربر ازبین نمیرود. |
جدول ۲: حالتهایی که برنامه تولیدکننده نوشتار تصادفی باید مدیریت کند.
بخشهای زیر نحوه مدیریت صحیح وضعیت دادههایتان را ازطریق عملیات مخرب شرح میدهد.
مشاهده ایالت
نماها مسئول مدیریت وضعیت خودشان هستند. برای مثال، وقتی
نمایی ورودی کاربر را میپذیرد، مسئولیت ذخیره و بازیابی
آن ورودی برای رسیدگی به تغییرات پیکربندی برعهده آن نما است. همه نماهای ارائهشده توسط چارچوب Android
پیادهسازی خاص خودشان را از onSaveInstanceState() و
onRestoreInstanceState() دارند، بنابراین لازم نیست وضعیت نما را در
تکه خودتان مدیریت کنید.
برای مثال، در سناریو قبلی، رشته ویرایششده در
EditText نگهداری میشود. EditText مقدار نوشتاری را که نمایش میدهد و همچنین جزئیات دیگر، مانند ابتدا و انتهای هر نوشتار انتخابشده را میداند.
نمای موردنظر برای حفظ وضعیت خود به شناسه نیاز دارد. این شناسه باید در قطعه و سلسلهمراتب نمای آن منحصربهفرد باشد. نماهای بدون شناسه نمیتوانند وضعیت خود را حفظ کنند.
<EditText android:id="@+id/good_deed_edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" />
همانطور که در جدول ۱ ذکر شد، نماها ViewState خود را ازطریق همه عملیاتی که قطعه را برنمیدارند یا میزبان را ازبین نمیبرند ذخیره و بازیابی میکنند.
SavedState
قطعه شما مسئول مدیریت مقادیر کمی از حالت پویا است
که برای نحوه عملکرد قطعه ضروری هستند. بااستفاده از
Fragment.onSaveInstanceState(Bundle) میتوانید دادههای بهراحتی سریالیشده را حفظ کنید.
مشابه
Activity.onSaveInstanceState(Bundle)،
دادههایی که در بسته قرار میدهید ازطریق تغییرات پیکربندی
و مرگ پردازش و بازآفرینی حفظ میشوند و در
onCreate(Bundle)،
onCreateView(LayoutInflater, ViewGroup, Bundle)،
و
onViewCreated(View, Bundle)
قطعه شما دردسترس هستند.
با ادامه مثال قبلی، randomGoodDeed سندی است که به کاربر نشان داده میشود و isEditing پرچمی است که تعیین میکند آیا قطعه EditText را نشان دهد یا پنهان کند. این حالت ذخیرهشده باید بااستفاده از onSaveInstanceState(Bundle) حفظ شود، همانطور که در مثال زیر نشان داده شده است:
کاتلین
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putBoolean(IS_EDITING_KEY, isEditing) outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed) }
جاوا
@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)، مقدار ذخیرهشده را از
دسته بازیابی کنید:
کاتلین
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false) randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY) ?: viewModel.generateRandomGoodDeed() }
جاوا
@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(); } }
همانطور که در جدول ۱ ذکر شد، توجه داشته باشید که وقتی قطعه در پشته برگشت قرار میگیرد، متغیرها حفظ میشوند. Treating them as saved state ensures they persist through all destructive operations.
NonConfig
دادههای NonConfig باید خارج از قطعه شما قرار داده شود، مثلاً در
ViewModel. در مثال قبلی در بالا، seed (وضعیت NonConfig ما) در ViewModel تولید میشود.
منطق حفظ وضعیت آن متعلق به ViewModel است.
کاتلین
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 } }
جاوا
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 اجازه میدهد تا حالت ساده را ازطریق
مرگ پردازش و بازآفرینی حفظ کند.
منابع بیشتر
برای اطلاعات بیشتر درباره مدیریت وضعیت قطعه، منابع تکمیلی زیر را ببینید.