Is there technically any reason why I should use onRestoreInstanceState? Could I not do all the restoration in onCreate by checking if the savedInstanceState bundle is null? What is the primary benefit of using onRestoreInstanceState over doing everything in onCreate?
onRestoreInstanceState
This method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation.
onRestoreInstanceState guarantees you receive a non-null Bundle object also in the lifecycle of activity it's called after onStart
But onCreate: you should always check if the Bundle object is null or not to determine the configuration change and as you know it's called before onStart
So It's all up to you and depends on your needs.
Mostly I tend to use onCreate(Bundle) to restore activity state, but if you have some initializations after which you want to restore the state its better to use onRestoreInstanceState() which offers much flexibility to restore state by the subsclasses those are extending the current activity. Also to be noted onRestoreInstanceState() is called after onStart() whereas onCreate(bundle) is called before that.
If you have huge data you can implement ViewModel class which handles the UI controller logic. ViewModel objects are automatically retained during configuration changes so that data they hold is immediately available to the next activity or fragment instance. For example, if you need to display a list of users in your app, make sure to assign responsibility to acquire and keep the list of users to a ViewModel, instead of an activity or fragment.
It also provides de-coupling and making your activity or fragment serve a single purpose rather than handling excessive responsibility of UI logic.
In my opinion, we can see this doc Restore activity UI state using saved instance state .
here are some points
1.Both the onCreate() and onRestoreInstanceState() callback methods receive the same Bundle that contains the instance state information.
2.Instead of restoring the state during onCreate() you may 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:
Related
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?
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.
When We can call onSaveInstanceState() to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(Bundle) or onRestoreInstanceState(Bundle)
Why the Bundle populated by this method will be passed to both these callbacks?
Is there any specific reason behind it.
Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).
-- http://developer.android.com/reference/android/app/Activity.html#onRestoreInstanceState%28android.os.Bundle%29#
onRestoreInstanceState exists for inheritance convenience.
What is the different between to reinitialize data of Activity in onCreate() and onRestoreInstanceState()
I am getting bundle in oncreate aslo.So My question is why I am not able to set data in oncreate method while the same thing is done in onRestoreInstantstate..Then what is the use of bundle object in oncreate i went through different tutorial but not got relevant answer so please if any one know the difference that where does we use the implementation to reinitialize the data of activity that whether it should be in onCreate or onRestoreInstanceState................please let me know
#numan salati Said:
onRestoreInstanceState is redundant because you can easily restore state in onCreate.
Having said that here is what the official doc says for
onRestoreInstanceState:
Most implementations will simply use onCreate(Bundle) to restore their
state, but it is sometimes convenient to do it here after all of the
initialization has been done or to allow subclasses to decide whether
to use your default implementation.
So for best practice, lay out your view hierarchy in onCreate and
restore the previous state in onRestoreInstanceState. If you do that,
anyone who subclasses your Activity can chose to override your
onRestoreInstanceState to augment or replace your restore state logic.
This is a long way of saying onRestoreInstanceState serves as a
template method.
Here
In onCreate(Bundle savedInstanceState), there`s already super.onCreate(savedInstanceState).
API says it restores states when create activity after destroyed.
But I have to override onSavedInstanceState(Bundle outState) for restore specific states.
Why?
What kind of informations are saved in savedInstanceState with method onCreate() and onSavedInstanceState()?
I'm so confused!
By default, when your device changes configuration (for example, devices rotates, you changed language settings, etc.), your foreground Activity is recreated, and all you Activity data is lost. For example, if you have a member variable mVariable that was assigned some value, after configuration change you will lose its value. That's why you need to save important data to savedInstanceState and re-init it from onCreate() method. You simply check whether savedInstanceState is not null, and if so, you init your values from savedInstance, else - init with default values.
Further reading: http://developer.android.com/training/basics/activity-lifecycle/recreating.html
onSaveInstanceState() is called before your activity is paused. So any info that it needs after it is potentially destroyed can be retrieved from the saved Bundle. The Bundle is a container for all the information you want to save. You use the put* functions to insert data into it. To get the data back out, use the get* functions just like the put* functions. The data is stored as a name-value pair. There isn't a specific use of this element, you can use it in any case (save a name, a number or whatever you need to have again when the use open again the app)
For restoring the state of the activity after it is recreated (for instance after the screen-orientation change) I implemented onSaveInstanceState() and onRestoreInstanceState(). It is simple to save/restore simple information like int, double etc. But what about saving/restoring objects like Timer?
You cannot store "live" objects (like db connections) in the Activity arguments or saved instance data. Those mechanisms are designed so that the application can be completely stopped, so it only works with things that can be "serialized" and later restored.
What you can do is use fragments. If you add a fragment without UI (check here, look for
“Adding a fragment without a UI”) and call on it setRetainInstance(true) the fragment will get reattached to the activity, surviving any configuration change.
Hope it helps. (Remember you can use fragments with old Android versions by using the support package)