When is the savedInstanceState bundle actually used? - android

Does anyone know of an exhaustive list of when the savedInstanceState bundle will be used in an activity?
I know it's used when the device orientation changes. However, it doesn't seem to be used when the user force closes the app from the Android settings, but this might be due to something in my code.
What other cases are there?
To be clear, by "used" I mean when onCreate() is called, the savedInstanceState bundle is not null and contains the data I passed into it the last time onSaveInstanceState() was called.

It's used when the Activity is forcefully terminated by the OS (ex: when your Activity is in the background and another task needs resources). When this happens, onSaveInstanceState(Bundle outstate) will be called and it's up to your app to add any state data you want to save in outstate.
When the user resumes your Activity, onCreate(Bundle savedInstanceState) gets called and savedInstanceState will be non-null if your Activity was terminated in a scenario described above. Your app can then grab the data from savedInstanceState and regenerate your Activity's state to how it was when the user last saw it.
Basically in onCreate, when savedInstanceState is null, then it means this is a 'fresh' launch of your Activity. And when it's non-null (if your app saved the data in onSaveInstanceState(...), it means the Activity state needs to be recreated.

onSaveInstanceState is used to store data only for application lifetime (i.e. temporarily)
The data is held in memory only until the application is alive, in other words this data is lost when the application closes, so in your case when you force close the app onSaveInstanceState is not used.
It can only be called when you do operations while your application is still alive, for e.g. when you change the screen orientation the activity is still intact so onSaveInstanceState is called.
However if you want to permanently store the data you would have to use SharedPreferences and SQLite database.

Related

why the application is recreated but the activity's onCreate still has the savedInstanceState passed in

Having a bug which relate to the os kill/restore the activity (or the app?).
After some debug find if set don't keep activities and set Background process limit to no background process will cause different behavior.
saw this post, but it does not answer the question here.
Here is what observed:
In the application it will start dagger component and it maintains some app scope singleton object, and in activity A (the default launch activity) it will by user's action to launch activity B, in B it creates and hosts a fragment. There will be some data stored in the app scope singleton object to work with the fragment.
In case of only have the don't keep activities set, when minimize the app the activities onDestroy() is called, and when re-open the app it restores the last active activity (say the user opened the activity B, the B will be re-created with the fragment restored with the savedInstanceState). In this case the app scope singleton objects managed by the dagger are still alive, so the state is completely restored to what it was before minimized the app.
But if have both don't keep activities and set Background process limit to no background process, then when minimize the app, the activity's onDestroy() is not call (only call up to the onStop()).
The behavior change is at this time if re-open the app, it will start from application onCreate(), and recreate the dagger's component. So the state before minimize the app is not re-stored.
But the os seems still remembers the last activity is B and the B's
onCreate(savedInstanceState: Bundle?)
is called with savedInstanceState having the data saved when minimizing the app, so does B's fragment.
And it is a messed up, it has data from the savedInstanceState, but the app scope singleton objects are fresh ones that do not have the data to work with the ones from the savedInstanceState.
Anyone knows in this case where is the savedInstance saved, and why although the application seems to be recreated but still the last activity (not the launching activity) is re-stored?
The savedInstanceState bundle is explicitly intended to do as you describe. Regardless of whether a background activity is destroyed to conserve memory (e.g. "don't keep activities" is turned on) or whether an entire app process is killed to conserve memory (e.g. "background process limit" is zero), the framework will provide your app the ability to save state information into the savedInstanceState bundle and will subsequently return that state information to you in future calls to onCreate().
The only situation in which savedInstanceState will be null is the very first time your activity starts up. It doesn't matter whether your app's process is killed or not; if your activity is restored you will receive a non-null savedInstanceState bundle.

ContainerHolderSinglton.getContainerHolder().getContainer() becomes null when resume app after some time

when we resume app after some time ContainerHolderSinglton.getContainerHolder().getContainer() becomes null
I assume this happens when your app is in the background for some time, and you come back to the application.
This happens because your App's process gets killed as Android system need resources.
You should save all the variables you want restored in the onSaveInstanceState() method of your Activity / Fragments. You should save the variables inside the singletons and restore them in onCreate(Bundle savedInstanceState) method, from the savedInstanceState.
Android Activity Lifecycle

onSaveInstanceState and finish()

Short question: Is it possible to save data using onSaveInstanceState() method, then call finish() on Activity and upon next start of the Activity to get the data back in savedInstanceState? Or does finish() of an Activity mean the data are gone?
If first answer is correct, I have some problem in my implementation because I am getting null in onCreate() although the data was saved. If second answer is correct, I will have to re-think how I connect my Activities together :o)
Is it possible to save data using onSaveInstanceState() method, then call finish() on Activity and upon next start of the Activity to get the data back in savedInstanceState?
No.
Or does finish() of an Activity mean the data are gone?
Yes. The saved instance state Bundle is for cases where, from the user's perspective, your activity is still around, but it is being destroyed for technical reasons:
Configuration changes (e.g., screen rotation)
Process termination (with the user returning to your app fairly quickly)
If finish() is called for other reasons — you calling it directly, user presses BACK, etc. — then the saved instance state is no longer needed and can be discarded.
As a result, the saved instance state Bundle is for transient data that you would like to retain but are comfortable with losing in the face of configuration changes and process termination, such as the contents of a partially-filled-in form.

Restore activity after destruction ?(Activity Lifecycle) Help needed

Hi guys i have an app which is almost totally complete.It is a music player.It plays music from a service.
When i press back button that activity which started the service is obviously destroyed.(i want the activity to be destroyed so that the user can navigate other activities.The reason i am telling this is because singleton|singleinstance etc won't solve my problem) But i don't know how i can recreate the activity from the notification.
Also when the activity which started the service is visible(and not destroyed) then too if i click on the notification, my app stops unexpectedly.And hence i have two problems to solve here.
I am using a global variable which is a list and hence i don't think i need to save data before destruction.I think i know the concept how the activity state can be restored and recreated but i think i am not totally aware how it can be done.I am not sure in which method the activity state should be restored and how can it be restored ??Also i am starting the service in onCreate method.Should i change it to some other method?Can starting the service in onCreate be a problem when restoring the activity ?
Extra Note :Global Variables are available throughout the application and are independent of an individual activity,as they extend Application.Also Bundle will only help when the activity is destroyed by the system.When Pressing the back button we explicitly destroy the activity and hence data cannot be saved into the bundle as onSaveInstanceState is never called by the activity.
Activity state should be restored in onCreate. The onCreate method gets a Bundle as parameter which contains key-value pairs of data. If this parameter is null, it means that no previous state was saved. Just check if it's not null, and restore things if necessary:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
...
if(savedInstanceState!=null) {
// Restore activity state based on saved data!
}
}
Of course you need to save data if you want to use it at restoration. System automatically calls the activity's onSaveInstance state method in which you can put data into the bundle.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("key", value); // Store data
}
Please note that this all applies to the case when system destroys your application automatically. (For example, when other apps in the foreground run out of memory.) This mechanism is to get your activity back to a state in which the user last saw it.
If the data is consistent and reflects with the Service, then you need to bind to the Service and get the data from the IBinder (which can wrap a Service object). I, personally, prefer this method because I simply don't like overriding the Application.
An alternate method is to save data via the SharedPreferences. Save it your Activity state in onPause() and restore in onCreate(). Assuming you're not saving hundreds of items, it is very low overhead. This should only be used for data that reflects the state of the Activity itself.
You can play and stop your player based on Activity life cycle like
OnPause -you should call player.stop()
onresume you should call play and
ondestroy you need to release your player instance.
call a thread inside your service to get data from server so that it will work smoothly.
you should release mediaplayer instances by calling release or reset .
You can use Pending intent in notification so when you will see notification then you can open your activity whatever mentioned in pending intent.

Android: Saving a state during Android lifecycle

I am refering to http://developer.android.com/reference/android/app/Activity.html.
I have an activity which can be "interrupted" by the user, e.g. the user opens the menu to call the preferences screen. When calling the preference screen onSaveInstanceState(Bundle) is called and I can save my data. That's fine so far. But upon pressing the back button onRestoreInstanceState(Bundle savedInstanceState) is NOT called.
So how can I save my state? Do I have to do it when calling the new activity? But how?
The only way I can think of, is saving the state by passing the state to the new activity, do nothing there with the saved data, return it to the first activity and restore the state in onActivitResult. But that would mean that I have to pass data back and forth just to restore the state. Doesn't seem to be a nice solution.
Probably a bad answer, but are you sure onRestoreInstanceState needs to be called?
The point of the bundle and onSaveInstanceState / onCreate with bundle / onRestoreInstanceState is to save transient data for an activity that is in the history stack, in case the activity must be killed to reclaim some memory. If it is killed, the activity can be restored, as if it were never killed, via onCreate / onRestonreInstanceState. However, if the activity was not killed, there may be no need to restore its transient data - presumably it is just as it was.
The Android documentation is careful to point out that onSaveInstanceStae / onRestoreInstanceState are not lifecycle methods, so aren't guaranteed to be called during lifecycle state transitions. If you need to hook into certain lifecycle transitions, take a look at the lifecycle hook methods. For example, onResume is called when the activity becomes the foreground activity and onPause is called when it is no longer the foreground activity.
Have a look at the Application Fundamentals, specifically this part:
Unlike onPause() and the other methods discussed earlier, onSaveInstanceState() and onRestoreInstanceState() are not lifecycle methods. They are not always called. For example, Android calls onSaveInstanceState() before the activity becomes vulnerable to being destroyed by the system, but does not bother calling it when the instance is actually being destroyed by a user action (such as pressing the BACK key). In that case, the user won't expect to return to the activity, so there's no reason to save its state.
Because onSaveInstanceState() is not always called, you should use it only to record the transient state of the activity, not to store persistent data. Use onPause() for that purpose instead.
Basically, any persistant data should be written out in your onPause() method and read back in onResume(). Check out the Data Storage article for ways of saving data.
Your ListView should not be cleared after returning from the Pref screen unless the Activity has been destroyed while the Pref screen was showing (in which case onCreate should have been called with the saved bundle).
The savedInstanceState is only used when the Activity has been destroyed and needs to be recreated. In this case, it looks like your ListActivity has not been destroyed.
Are you clearing your ListView manually somewhere?

Categories

Resources