Obnovení stavu (State Restoration) je mechanismus mobilních operačních systémů, který umožňuje ukládat a obnovovat uživatelské rozhraní aplikace po jejím restartu nebo minimalizaci. Systém ukládá stav UI do paměti nebo trvalého úložiště a obnovuje jej při opětovném otevření. Podle údajů Android Developers (2025) je State Restoration povinný pro aplikace usilující o kvalitní uživatelský zážitek. State Restoration je kriticky důležitý pro prevenci ztráty dat při neočekávaném ukončení aplikace.
Hlavní body
State Restoration (obnovení stavu) je systémový mechanismus, který umožňuje ukládat aktuální stav uživatelského rozhraní aplikace a obnovovat jej po uzavření nebo restartu. Když uživatel minimalizuje aplikaci nebo systém ji uzavře za účelem uvolnění zdrojů, State Restoration zaznamená klíčové parametry UI a uloží je do šifrovaného úložiště.
Bez State Restoration uživatel ztrácí všechna neuložená data při přepínání mezi aplikacemi. Například vyplněný kontaktní formulář, dlouhý vyhledávací dotaz nebo částečně prohlédnutý seznam zpráv — vše zmizí při restartu. State Restoration řeší tento problém automatickým zaznamenáním stavu ViewController nebo Activity v okamžiku minimalizace.
Mechanismus funguje na systémové úrovni a je podporován oběma hlavními mobilními platformami. iOS poskytuje State Restoration přes NSUserActivity a protokol UIStateRestoring, Android přes SavedStateHandle v architektonických komponentách Jetpack a ViewModel. Implementace se liší, ale koncept je identický.
Proces State Restoration je rozdělen do dvou fází: ukládání (save) a obnovování (restore). Ve fázi ukládání systém volá odpovídající metody životního cyklu, ve kterých aplikace musí serializovat aktuální stav UI do kompaktní reprezentace. Ve fázi obnovování systém předá uložená data zpět a aplikace je deserializuje pro obnovení UI.
Ukládání je iniciováno systémem při přechodu aplikace do pozadí nebo při obdržení signálu o blížícím se ukončení. V iOS je volána metoda encodeRestorableState v UIViewController, v Android onSaveInstanceState v Activity nebo ukládání přes SavedStateHandle. Data jsou serializována do formátu podporujícího primitivní typy: řetězce, čísla, pole bajtů a objekty Parcelable.
Objem ukládaných dat by měl být minimální — systém ukládá omezení na velikost ukládaného balíku. V Androidu je limit přibližně 50 KB na proces. Překročení limitu vede k výjimce TransactionTooLargeException. Proto architekti doporučují ukládat pouze identifikátory a klíče a plná data načítat z trvalého úložiště při obnovení.
Při obnovení systém předá uložený datový balík aplikaci v okamžiku spuštění. V iOS je volána metoda decodeRestorableState, v Android onRestoreInstanceState nebo čtení ze SavedStateHandle. Aplikace extrahuje identifikátory a klíče z balíku a obnoví UI: pozici posouvání, vybrané prvky, zadaná data.
Je důležité vzít v úvahu, že k obnovení může dojít v novém procesu. Pokud byla aplikace zcela uvolněna z paměti, proces je vytvořen znovu a všechny objekty v paměti chybí. Stav proto musí být serializovatelný a nezávislý na běhovém kontextu předchozí relace. To je obzvláště kritické pro velké formuláře s mnoha vstupními poli a dlouhá vícestránková rozhraní.
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)
}
}
Implementace State Restoration se mezi platformami významně liší. iOS používá deklarativní přístup přes storyboard a protokoly UIKit, zatímco Android používá imperativní přístup přes metody životního cyklu Activity a architektonické komponenty Jetpack. Volba přístupu závisí na cílové platformě a architektuře aplikace.
V iOS je State Restoration postaven na třech komponentách: UIApplication řídí celkový proces, UIViewController implementuje protokol UIStateRestoring a NSUserActivity ukládá data pro obnovení navigace. Pro aktivaci je třeba nastavit restorationIdentifier v UIViewController a implementovat encodeRestorableState a decodeRestorableState.
iOS automaticky ukládá stav navigačního kontroleru (UINavigationController) a všech vnořených ViewController, pokud mají nastavený restorationIdentifier. Systém spravuje zásobník navigace a obnovuje jej v původním stavu. Data uvnitř kontrolerů (zadaný text, pozice posouvání) však musí být explicitně uložena vývojářem.
V Androidu je moderní přístup k State Restoration založen na SavedStateHandle — komponentě z knihovny AndroidX Lifecycle. SavedStateHandle je dostupný uvnitř ViewModel a automaticky ukládá a obnovuje data při změně konfigurace (otočení obrazovky) a při restartu procesu. Data jsou uložena v Bundle a automaticky serializována.
SavedStateHandle se chová jako úložiště klíč-hodnota s podporou LiveData. Při změně konfigurace jsou data automaticky uložena a obnovena. Pro podporu restartu procesu musí být ViewModel vytvořen přes SavedStateViewModelFactory — to umožňuje ViewModel přežít úplné ukončení aplikace.
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
}
}
Praktická implementace State Restoration vyžaduje zohlednění několika aspektů: výběr správného úložiště, určení objemu ukládaných dat a testování různých scénářů ukončení. Podívejme se na implementaci krok za krokem pro aplikaci Flutter s použitím balíčku 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 ?? '';
}
}
Při implementaci je důležité pamatovat na hranice ukládání. Ne každé pole UI je třeba obnovovat. Pozice posouvání v dlouhém seznamu — ano. Dočasný stav animace — ne. Vývojář by měl vědomě vybírat, která data jsou kritická pro uživatelský zážitek a která lze bezpečně resetovat bez ztráty pohodlí.
Testování State Restoration je samostatný úkol vyžadující simulaci ukončení procesu. Na Androidu to lze provést příkazem adb shell am kill, na iOS simulací ukončení v Xcode. Rámce pro testování UI, jako jsou Espresso a XCTest, poskytují speciální metody pro kontrolu obnovení stavu.
První pravidlo — ukládejte identifikátory, nikoli data. Místo ukládání celého objektu se stovkami polí uložte jeho jedinečný identifikátor a při obnovení načtěte aktuální data z databáze nebo API. To šetří místo v Bundle a zaručuje aktuálnost dat v okamžiku obnovení.
Druhé pravidlo — testujte všechny scénáře. Zkontrolujte obnovení po otočení obrazovky, po minimalizaci a návratu po hodině, po ukončení aplikace systémem z důvodu nedostatku paměti. Každý scénář se může chovat jinak v závislosti na stavu operačního systému a dostupných zdrojích.
Třetí pravidlo — používejte systémové mechanismy, ne vlastní. iOS a Android poskytují vestavěná API pro State Restoration optimalizovaná pro danou platformu. Vlastní implementace přes SharedPreferences nebo UserDefaults může vést k problémům se synchronizací a neočekávanému chování při obnovení.
Čtvrté pravidlo — ošetřete absenci stavu. Při prvním spuštění nebo po vymazání dat může stav chybět. UI musí správně fungovat ve výchozím stavu bez vyhazování výjimek. Před použitím zkontrolujte všechna uložená data na null a zajistěte výchozí hodnoty.
Páté pravidlo — dokumentujte ukládané klíče. Když je v projektu desítky obrazovek a každá ukládá několik polí, bez centralizované správy klíčů vzniká chaos. Vytvořte jednotnou třídu nebo soubor s konstantami klíčů pro State Restoration v každém modulu. To zjednodušuje údržbu a zabraňuje náhodnému přepsání dat při refaktorování.
Často kladené otázky
State Restoration — mechanismus ukládání a obnovování uživatelského rozhraní aplikace po restartu nebo minimalizaci, zabraňující ztrátě dat a pracovního kontextu uživatele.
State Restoration ukládá dočasný stav UI (pozici posouvání, zadaná data ve formuláři), zatímco databáze ukládá trvalá uživatelská data. State Restoration používá systémové mechanismy (Bundle, NSData) s omezením objemu.
Použijte SavedStateHandle ve ViewModel z AndroidX Lifecycle. Automaticky ukládá data při minimalizaci a obnovuje je při návratu. Pro podporu úplného restartu použijte SavedStateViewModelFactory.
Nastavte restorationIdentifier v UIViewController a implementujte metody encodeRestorableState a decodeRestorableState. Pro navigaci použijte NSUserActivity s uložením cesty v zásobníku kontrolerů.
Ukládejte identifikátory, nikoli plná data: ID vybraného prvku, vyhledávací dotaz, pozici posouvání, stav přepínačů. Vyhněte se ukládání velkých objektů a obrázků.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také