بازیابی حالت (State Restoration) مکانیزمی از سیستمعاملهای موبایل است که به ذخیره و بازیابی رابط کاربری برنامه پس از راهاندازی مجدد یا کوچکسازی آن اجازه میدهد. سیستم وضعیت UI را در حافظه یا ذخیرهسازی دائمی حفظ کرده و هنگام بازگشایی مجدد آن را بازیابی میکند. به گفته Android Developers (2025)، State Restoration برای برنامههایی که به تجربه کاربری باکیفیت ادعا دارند الزامی است. State Restoration برای جلوگیری از از دست رفتن دادهها در هنگام بسته شدن غیرمنتظره برنامه حیاتی است.
نکات اصلی
State Restoration (بازیابی حالت) مکانیزمی سیستمی است که به ذخیره وضعیت فعلی رابط کاربری برنامه و بازیابی آن پس از بسته شدن یا راهاندازی مجدد اجازه میدهد. هنگامی که کاربر برنامه را کوچک میکند یا سیستم آن را برای آزادسازی منابع میبندد، State Restoration پارامترهای کلیدی UI را ثبت کرده و در یک ذخیرهگاه رمزگذاریشده نگهداری میکند.
بدون State Restoration، کاربر هنگام جابجایی بین برنامهها تمام دادههای ذخیرهنشده را از دست میدهد. برای مثال، فرم تماس پر شده، جستجوی طولانی یا فهرست خبری که تا نیمه مشاهده شده است — همه اینها هنگام راهاندازی مجدد ناپدید میشوند. State Restoration این مشکل را حل میکند و به طور خودکار وضعیت ViewController یا Activity را در لحظه کوچکسازی ثبت میکند.
این مکانیزم در سطح سیستم کار میکند و توسط هر دو پلتفرم اصلی موبایل پشتیبانی میشود. iOS State Restoration را از طریق NSUserActivity و پروتکل UIStateRestoring ارائه میدهد و Android از طریق SavedStateHandle در مؤلفههای معماری Jetpack و ViewModel. پیادهسازی متفاوت است اما مفهوم یکسان است.
فرآیند State Restoration به دو فاز تقسیم میشود: ذخیره (save) و بازیابی (restore). در فاز ذخیره، سیستم متدهای مربوطه چرخه حیات را فراخوانی میکند که در آن برنامه باید وضعیت فعلی UI را به یک نمایش فشرده سریالسازی کند. در فاز بازیابی، سیستم دادههای ذخیرهشده را باز میگرداند و برنامه آنها را برای بازیابی UI دیسریالسازی میکند.
ذخیره توسط سیستم هنگام انتقال برنامه به حالت پسزمینه یا دریافت سیگنال بسته شدن قریبالوقوع آغاز میشود. در iOS متد encodeRestorableState در UIViewController فراخوانی میشود، در Android متد onSaveInstanceState در Activity یا ذخیره از طریق SavedStateHandle. دادهها به فرمتی سریالسازی میشوند که انواع ابتدایی را پشتیبانی میکند: رشتهها، اعداد، آرایههای بایت و اشیاء Parcelable.
حجم دادههای ذخیرهشده باید حداقل باشد — سیستم محدودیتهایی بر اندازه بسته ذخیرهشده اعمال میکند. در Android این محدودیت تقریباً 50 کیلوبایت به ازای هر فرآیند است. تجاوز از محدودیت منجر به استثنای TransactionTooLargeException میشود. بنابراین معماران توصیه میکنند فقط شناسهها و کلیدها را ذخیره کرده و دادههای کامل را هنگام بازیابی از ذخیرهسازی دائمی بارگذاری کنند.
هنگام بازیابی، سیستم بسته داده ذخیرهشده را در لحظه راهاندازی به برنامه تحویل میدهد. در iOS متد decodeRestorableState فراخوانی میشود، در Android متد onRestoreInstanceState یا خواندن از SavedStateHandle. برنامه شناسهها و کلیدها را از بسته استخراج کرده و UI را بازیابی میکند: موقعیت اسکرول، عناصر انتخابشده، دادههای واردشده.
توجه به این نکته مهم است که بازیابی ممکن است در یک فرآیند جدید رخ دهد. اگر برنامه به طور کامل از حافظه تخلیه شده باشد، فرآیند از نو ایجاد میشود و تمام اشیاء در حافظه وجود ندارند. بنابراین وضعیت باید قابل سریالسازی و مستقل از زمینه اجرای جلسه قبلی باشد. این امر به ویژه برای فرمهای بزرگ با فیلدهای ورودی متعدد و رابطهای طولانی چندصفحهای حیاتی است.
class MainActivity : AppCompatActivity() {
private var searchQuery: String = ""
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("search_query", searchQuery)
}
override fun onRestoreInstanceState(savedState: Bundle) {
super.onRestoreInstanceState(savedState)
searchQuery = savedState.getString("search_query", "")!!
restoreSearchUI(searchQuery)
}
}
پیادهسازی State Restoration بین پلتفرمها تفاوت قابل توجهی دارد. iOS از رویکرد اعلامی از طریق storyboard و پروتکلهای UIKit استفاده میکند، در حالی که Android از رویکرد امری از طریق متدهای چرخه حیات Activity و مؤلفههای معماری Jetpack استفاده میکند. انتخاب رویکرد به پلتفرم هدف و معماری برنامه بستگی دارد.
در iOS، State Restoration بر سه مؤلفه استوار است: UIApplication فرآیند کلی را مدیریت میکند، UIViewController پروتکل UIStateRestoring را پیادهسازی میکند و NSUserActivity دادهها را برای بازیابی ناوبری ذخیره میکند. برای فعالسازی باید restorationIdentifier را در UIViewController تنظیم کرده و متدهای encodeRestorableState و decodeRestorableState را پیادهسازی کنید.
iOS به طور خودکار وضعیت کنترلکننده ناوبری (UINavigationController) و تمام ViewControllerهای تو در تو را ذخیره میکند اگر آنها دارای restorationIdentifier تنظیم شده باشند. سیستم پشته ناوبری را مدیریت کرده و آن را در حالت اصلی خود بازیابی میکند. اما دادههای داخل کنترلکنندهها (متن واردشده، موقعیت اسکرول) باید به صراحت توسط توسعهدهنده ذخیره شوند.
در Android، رویکرد مدرن به State Restoration بر SavedStateHandle استوار است — مؤلفهای از کتابخانه AndroidX Lifecycle. SavedStateHandle در داخل ViewModel در دسترس است و به طور خودکار دادهها را هنگام تغییر پیکربندی (چرخش صفحه) و هنگام راهاندازی مجدد فرآیند ذخیره و بازیابی میکند. دادهها در Bundle ذخیره و به طور خودکار سریالسازی میشوند.
SavedStateHandle مانند یک ذخیرهگاه کلید-مقدار با پشتیبانی از LiveData رفتار میکند. هنگام تغییر پیکربندی، دادهها به طور خودکار ذخیره و بازیابی میشوند. برای پشتیبانی از راهاندازی مجدد فرآیند، ViewModel باید از طریق SavedStateViewModelFactory ایجاد شود — این به ViewModel اجازه میدهد از بسته شدن کامل برنامه جان سالم به در ببرد.
class SearchViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
companion object {
private val KEY_QUERY = string("search_query")
}
fun getSearchQuery(): String? = savedStateHandle[KEY_QUERY]
fun saveSearchQuery(query: String) {
savedStateHandle[KEY_QUERY] = query
}
}
پیادهسازی عملی State Restoration نیازمند در نظر گرفتن چندین جنبه است: انتخاب ذخیرهگاه مناسب، تعیین حجم دادههای ذخیرهشده و آزمایش سناریوهای مختلف بسته شدن. بیایید پیادهسازی گامبهگام برای برنامه Flutter با استفاده از بسته state_restoration را بررسی کنیم.
class RestorableSearchField extends RestorableProperty<String> {
String _value = '';
@override
String get value => _value;
@override
void set value(String newValue) {
if (_value != newValue) {
_value = newValue;
notifyListeners();
}
}
@override
String? toPrimitives() => _value;
@override
void fromPrimitives(String? data) {
_value = data ?? '';
}
}
در پیادهسازی، مهم است که مرزهای ذخیره را به خاطر بسپارید. هر فیلد UI نیاز به بازیابی ندارد. موقعیت اسکرول در یک لیست طولانی — بله. وضعیت موقت انیمیشن — خیر. توسعهدهنده باید آگاهانه انتخاب کند که کدام دادهها برای تجربه کاربری حیاتی هستند و کدامها را میتوان بدون کاهش راحتی با خیال راحت بازنشانی کرد.
آزمایش State Restoration یک وظیفه جداگانه است که نیاز به شبیهسازی پایان فرآیند دارد. در Android این کار از طریق دستور adb shell am kill و در iOS از طریق شبیهسازی پایان در Xcode قابل انجام است. چارچوبهای تست UI مانند Espresso و XCTest روشهای خاصی برای بررسی بازیابی وضعیت ارائه میدهند.
قانون اول — شناسهها را ذخیره کنید، نه دادهها. به جای ذخیره یک شی کامل با صدها فیلد، شناسه یکتای آن را ذخیره کرده و هنگام بازیابی دادههای بهروز را از پایگاه داده یا API بارگذاری کنید. این کار در Bundle صرفهجویی میکند و بهروز بودن دادهها را در لحظه بازیابی تضمین میکند.
قانون دوم — همه سناریوها را آزمایش کنید. بازیابی را پس از چرخش صفحه، پس از کوچکسازی و بازگشت پس از یک ساعت، پس از بسته شدن برنامه توسط سیستم به دلیل کمبود حافظه بررسی کنید. هر سناریو بسته به وضعیت سیستمعامل و منابع موجود ممکن است رفتار متفاوتی داشته باشد.
قانون سوم — از مکانیزمهای سیستمی استفاده کنید، نه مکانیزمهای خودساخته. iOS و Android APIهای داخلی برای State Restoration ارائه میدهند که برای پلتفرم خاص بهینه شدهاند. پیادهسازی شخصی از طریق SharedPreferences یا UserDefaults میتواند منجر به مشکلات همگامسازی و رفتار غیرمنتظره هنگام بازیابی شود.
قانون چهارم — عدم وجود وضعیت را مدیریت کنید. در اولین راهاندازی یا پس از پاک کردن دادهها، وضعیت ممکن است وجود نداشته باشد. UI باید در وضعیت اولیه بدون ایجاد استثنا به درستی کار کند. تمام دادههای ذخیرهشده را قبل از استفاده از نظر null بررسی کرده و مقادیر پیشفرض را در نظر بگیرید.
قانون پنجم — کلیدهای ذخیرهشده را مستند کنید. وقتی در پروژه دهها صفحه وجود دارد و هر کدام چندین فیلد ذخیره میکنند، بدون مدیریت متمرکز کلیدها هرج و مرج ایجاد میشود. یک کلاس یا فایل واحد با ثابتهای کلید برای State Restoration در هر ماژول ایجاد کنید. این کار نگهداری را ساده میکند و از بازنویسی تصادفی دادهها در بازسازی کد جلوگیری میکند.
سوالات متداول
State Restoration — مکانیزم ذخیره و بازیابی رابط کاربری برنامه پس از راهاندازی مجدد یا کوچکسازی که از از دست رفتن دادهها و زمینه کاری کاربر جلوگیری میکند.
State Restoration وضعیت موقت UI را ذخیره میکند (موقعیت اسکرول، دادههای واردشده در فرم)، در حالی که پایگاه داده دادههای دائمی کاربر را ذخیره میکند. State Restoration از مکانیزمهای سیستمی (Bundle، NSData) با محدودیت حجم استفاده میکند.
از SavedStateHandle در ViewModel از AndroidX Lifecycle استفاده کنید. این مؤلفه به طور خودکار دادهها را هنگام کوچکسازی ذخیره و هنگام بازگشت بازیابی میکند. برای پشتیبانی از راهاندازی مجدد کامل از SavedStateViewModelFactory استفاده کنید.
restorationIdentifier را در UIViewController تنظیم کرده و متدهای encodeRestorableState و decodeRestorableState را پیادهسازی کنید. برای ناوبری از NSUserActivity با ذخیره مسیر در پشته کنترلکنندهها استفاده کنید.
شناسهها را ذخیره کنید، نه دادههای کامل: ID عنصر انتخابشده، جستجوی انجامشده، موقعیت اسکرول، وضعیت کلیدها. از ذخیره اشیاء بزرگ و تصاویر خودداری کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید