Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving activity's state with onSaveInstanceState() and ViewModel

I was left with some questions regarding ViewModels after reading this:

https://developer.android.com/topic/libraries/architecture/saving-states

It says here that you should use a combination of both a ViewModel for configuration changes (like screen rotation), and using onSaveInstanceState() for all other cases where an activity is destroyed and then recreated in order to save the UI state.

My question is how do we know the way to restore the state when onCreate(Bundle) is called - should I use the ViewModel or should I use the bundle received as a parameter? When the configuration changes, onSaveInstanceState() is also called, and obviously onCreate() is always called.

If I only restore the state from a ViewModel, it won't always remain with the correct data (since the activity could have been destroyed due to other reasons than configuration changes). If I only use the bundle I save in onSaveInstanceState() then why would I use a ViewModel to begin with?

like image 215
Yonatan Nir Avatar asked Feb 23 '19 10:02

Yonatan Nir


People also ask

How do you save data on onSaveInstanceState?

In order to save sates of UI, I override onSaveInstanceState(Bundle savedInstanceState) and save all the data of the UI in savedInstanceState Bundle. This method is called before onStop() in older versions of Android (till android 8.0) and can be called after onStop() for newer versions. super.

How UI state is managed with ViewModel?

UI state is usually stored or referenced in ViewModel objects and not activities, so using onSaveInstanceState() requires some boilerplate that the saved state module can handle for you. When using this module, ViewModel objects receive a SavedStateHandle object through its constructor.

What should be done to preserve the state of an activity?

Use a combination of ViewModels, the onSaveInstanceState() method, and/or persistent local storage to preserve an activity's UI state across configuration changes.

How do I use onSaveInstanceState and onRestoreInstanceState on Android?

The onSaveInstanceState() method allows you to add key/value pairs to the outState of the app. Then the onRestoreInstanceState() method will allow you to retrieve the value and set it back to the variable from which it was originally collected.

What is the difference between onsaveinstancestate () and saved state of ViewModel?

onSaveInstanceState () can store a minimum number of data and not large amount of it. Saved State of ViewModel can be considered as a replacement for onSaveInstanceState () as it can also store the data because UI data is always referenced from ViewModel of Architecture Components and not the View (Activity/Fragment).

What is the use of onsaveinstancestate?

As mentioned in Saving UI States , ViewModel objects can handle configuration changes, so you don't need to worry about state in rotations or other cases. However, if you need to handle system-initiated process death, you might want to use onSaveInstanceState () as backup.

How to save and restore activity state in a ViewModel?

You pass the query from the onSaveInstanceState () bundle to the ViewModel, which will determine that it already has loaded the necessary data and that it does not need to re-query the database. This is one sane way to handle saving and restoring activity state.

What is onsaveinstancestate () in Android jetpack?

Saved State module for ViewModel Part of Android Jetpack. As mentioned in Saving UI States , ViewModel objects can handle configuration changes, so you don't need to worry about state in rotations or other cases. However, if you need to handle system-initiated process death, you might want to use onSaveInstanceState () as backup.


1 Answers

I think it's good to think of this sources as a chain. You have 2 sources of data - ViewModel, that is faster but lives less and saved instance state that is slower but lives longer.

The rule is simple - try using your ViewModel and if it is not populated use the bundle from onSaveInstanceState().

When you do val model = ViewModelProviders.of(this).get(MyViewModel::class.java) in onCreate() you can check if you get a new instance of viewModel. Then, if it is a new instance (i.e. it's data fields are empty) you can get some basic data from your bundle, like content id, and fetch data from the backend or database based on that id, populate your new ViewModel with it and then populate your activity from the ViewModel (if you are using LiveData it will be very natural).

Next time onCreate is called you repeat the process, either populating your activity from ViewModel or populating your ViewModel using data in the Bundle and then populating your activity from your ViewModel.

Update: Actually there is very similar approach described in the official docs. The only difference is that you pass the bundle to ViewModel and it decides if it needs fetching data, I was not specific about this mechanism.

like image 105
TpoM6oH Avatar answered Sep 18 '22 15:09

TpoM6oH