Android SavedState is used to save information regarding the UI’s state of your application. So when users will always come back to the application then find it in the same state they had left it in.
A process is created for every launched application on android for running. The application process is killed when the application is no longer in the foreground.
Use android SavedState in this case to allow users to present the application in the same state they left it in, even if its process may have been killed by the system.
Approaches:
For retaining a small amount of UI related data use onSaveInstanceState() in the following situations:
- When the application is in the background due to memory constraints its process stop.
- Configuration changes. The user rotates the device or does some other configuration change.
Call onSaveInstanceState() in situations when activity stops, but not finished, by the system. It is not in the case when the user explicitly closes the activity or in other cases, of finish() is call.
For retaining large and complex UI-related data use ViewModel which makes the code more modular by separating the data from UI code.
ViewModels always help to handle the situation of configuration changes because ViewModel is not destroying data on a configuration change.
But for the process stop situation ViewModel destroy as well so we need to restore UI data using onSaveInstance().
Implementation:
1. Initial setup:
Add below dependency in build.gradle in your app module.
1 |
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha02' |
2. Saving and retrieving ViewModel state with SaveStateHandle:
- Inside your ViewModel class add the SavedStateHandle object in its constructor.
- Now you need to define a key with which you save and restore the data because SavedStateHandle persists data as key-value like a map so keep a key as constant.
- Now save the item using the SavedStateHandle object using the key inside CustomerViewModel as:
1 2 3 |
fun saveCustomerToken(customerToken: String) { savedStateHandle.set(CUSTOMER_TOKEN, customerToken) } |
- Use the SavedStateHandle object with the key to get the saved value in SavedStateHandle
1 2 3 |
fun getCustomerToken(): String { return savedStateHandle.get(CUSTOMER_TOKEN)?: "" } |
- for live data use getLiveData() of SavedStateHandle
1 |
private val liveCustomerToken : LiveData<String> = savedStateHandle.getLiveData(CUSTOMER_TOKEN) |
Finally the ViewModel class will look like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class CustomerViewModel(savedState : SavedStateHandle) : ViewModel() { private val savedStateHandle = savedState companion object { private val CUSTOMER_TOKEN = "customerToken" } fun saveCustomerToken(customerToken: String) { savedStateHandle.set(CUSTOMER_TOKEN, customerToken) } fun getCustomerToken(): String { return savedStateHandle.get(CUSTOMER_TOKEN)?: "" } } |
3. Using ViewModel with your activity by ViewModelProvider call
In your activity or fragment’s onCreate, update your call to ViewModelProvider to:
1 2 |
val viewModel = ViewModelProvider(this, SavedStateVMFactory(this)) .get(CustomerViewModel::class.java) |
Conclusion:
In this blog, you have learned to persist data for UI state. Using this approach everywhere is not a good idea and is not a replacement over SharedPreferences sometimes a Room Database or SharedPreferences might work better.
Thanks for reading this blog. You can also check other blogs from here.