Saving and restoring an activity's UI state quickly after the system destroys activities or applications is essential for a good user experience. Users expect the UI state to stay the same, but the system might destroy the activity and its stored state.
o bridge the gap between user expectations and system behavior, use a combination of the following methods:
ViewModel objects.
Saved instance states within the following contexts:
Jetpack Compose: rememberSaveable.
Views: onSaveInstanceState() API.
ViewModels: SavedStateHandle.
Local storage to persist the UI state during app and activity transitions.
The optimal solution depends on your UI data's complexity, your app's use cases, and finding a balance between data access speed and memory use.
Make sure your app meets users' expectations and offers a fast, responsive interface. Avoid delays when loading data into the UI, particularly after common configuration changes like rotation.
Unlike saved instance state, ViewModels are destroyed during a system-initiated process death. To reload data after a system-initiated process death in a ViewModel, use the SavedStateHandle API. Alternatively, if the data is related to the UI and doesn't need to be held in the ViewModel, use onSaveInstanceState() in the View system or rememberSaveable in Jetpack Compose. If the data is application data, then it might be better to persist it to disk.
Saved instance state bundles persist through both configuration changes and process death but are limited by storage and speed, because the different APIs serialize data. Serialization can consume a lot of memory if the objects being serialized are complicated. Because this process happens on the main thread during a configuration change.
to store a minimal amount of data necessary, such as an ID, to re-create the data necessary to restore the UI back to its previous state should the other persistence mechanisms fail. Most apps should implement this to handle system-initiated process death.In cases where the UI data to preserve is simple and lightweight, you might use saved instance state APIs alone to preserve your state data.
To save additional instance state information for your activity, override onSaveInstanceState() and add key-value pairs to the Bundle object that is saved in the event that your activity is destroyed unexpectedly. When you override onSaveInstanceState()
Note: onSaveInstanceState() is not called when the user explicitly closes the activity or in other cases when finish() is called.
Restore activity UI state using saved instance state
When your activity is recreated after it was previously destroyed, you can recover your saved instance state from the Bundle that the system passes to your activity. Both the onCreate() and onRestoreInstanceState() callback methods receive the same Bundle that contains the instance state information.
Instead of restoring the state during onCreate(), you can choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null.
ViewModel is ideal for storing and managing UI-related data while the user is actively using the application.
ViewModel retains the data in memory, which means it is cheaper to retrieve than data from the disk or the network. A ViewModel is associated with an activity (or some other lifecycle owner) - it stays in memory during a configuration change and the system automatically associates the ViewModel with the new activity instance that results from the configuration change.
ViewModels are automatically destroyed by the system when your user backs out of your activity or fragment or if you call finish(), which means the state is cleared as the user expects in these scenarios.
Unlike saved instance state, ViewModels are destroyed during a system-initiated process death. To reload data after a system-initiated process death in a ViewModel, use the SavedStateHandle API.
Use local persistence to handle process death for complex or large data
In either of these scenarios, you should still use a ViewModel to avoid wasting cycles reloading data from the database during a configuration change.
In cases where the UI data to preserve is simple and lightweight, you might use saved instance state APIs alone to preserve your state data.
Use local persistence to handle process death for complex or large data
Key Point: the API to use depends on where the state is hold and the logic that it requires. For state that is used in business logic, hold it in a ViewModel and save it using SavedStateHandle. For state that is used in UI logic, use the onSaveInstanceState API in the View system or rememberSaveable in Compose.
Local persistence: Stores all the application data you don't want to lose if you open and close the activity.
Example: A collection of song objects, which could include audio files and metadata.
ViewModel: Stores in memory all the data needed to display the associated UI, the screen UI state.
Example: The song objects of the most recent search and the most recent search query.
Saved instance state: Stores a small amount of data needed to reload UI state if the system stops and then recreates the UI. Instead of storing complex objects here, persist the complex objects in local storage and store a unique ID for these objects in the saved instance state APIs.
Example: Storing the most recent search query.