درحال ذخیره وضعیت با قطعه‌ها

عملیات مختلف سیستم 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 اجازه می‌دهد تا حالت ساده را ازطریق مرگ پردازش و بازآفرینی حفظ کند.

منابع بیشتر

برای اطلاعات بیشتر درباره مدیریت وضعیت قطعه، منابع تکمیلی زیر را ببینید.

Codelabs

راهنماها