onSaveInstanceState is not getting called - android

I have an activity which starts various activities for result codes and on getting results in onActivityResult method it starts appropriate activity based on result code.
onSaveInstanceState is not getting called in Activity which started for result.
For example Navigation Activity starts Activity A as :
Intent intent = new Intent(this, A.class);
startActivityForResult(intent, Constants.REQUEST_CODE);
Then A finishes by setting result code so App will redirect to Navigation activity again and onActivityResult method will called.
So my question is: Why Activity A's onSaveInstanceState is not getting called at finish and navigation back to Navigation Activity ?

onSaveInstanceState() is only called if the Activity is being killed.
I don't know what exactly you want to do in that method, but you probably should move your code to the corresponding methods of the Activity Lifecycle.
from http://developer.android.com/reference/android/app/Activity.html :
Note that it is important to save persistent data in onPause() instead of onSaveInstanceState(Bundle) because the latter is not part of the lifecycle callbacks, so will not be called in every situation as described in its documentation.
Also the method description for onSaveInstanceState() describes exactly your situation:
Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction, or onStop() which is called before destruction. One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it. An example when onPause() is called and not onSaveInstanceState(Bundle) is when activity B is launched in front of activity A: the system may avoid calling onSaveInstanceState(Bundle) on activity A if it isn't killed during the lifetime of B since the state of the user interface of A will stay intact.

The method onSaveInstanceState() isn't called when an Activity finishes naturally like on a back button press. That's your app itself destroying the Activity. The method is only called if the Android OS anticipates that it may have to kill your activity to reclaim resources.
If the Activity then actually gets killed by Android, the OS will make sure you receive a call to onRestoreInstanceState() as well passing the same bundle you used to save your activity's state in onSaveInstanceState() method.
From the docs:
This method is called before an activity may be killed so that
when it comes back some time in the future it can restore its state.
For example, if activity B is launched in front of activity A, and at
some point activity A is killed to reclaim resources, activity A will
have a chance to save the current state of its user interface via this
method so that when the user returns to activity A, the state of the
user interface can be restored via onCreate(Bundle) or
onRestoreInstanceState(Bundle).

I had the same issue happening to me on a "drawer menu" part of a "main activity", because I had overridden the "onSaveInstanceState" method in my main activity but had forgotten the call to super.onSaveInstanceState() (which, as a result, would never call the "onSaveInstanceState()" method of my "drawer menu" which was part of this main activity).
In other words: make sure you don't forget your calls to "super.onSaveInstanceState()" where necessary.

Related

Is the activity's view recreated before its onActivityResult() called after an OS restart?

Let's say I have Activity A. I start Activity B from Activity A using startActivityForResult(), and whenever that's done, the setResult() fuction is called in Activity B, resulting in Activity's A onActivityResult() being called.
But what if while I'm in Activity B, the android OS kills the app and restarts it. When the app is restored, I'm back in Activity B and I then choose to return back to Activity A by calling setResult(). So my question is, is Activity A's view recreated(onCreate() called) before its onActivityResult() is called? In such a scenario, is Activity A's onActivityResult() even called?
Thanks for reading.
So my question is, is Activity A's view recreated(onCreate() called)
before its onActivityResult() is called? In such a scenario, is
Activity A's onActivityResult() even called?
Yes. If OS has killed the process of your app and Activity B is finished, the OS knows to recreate Activity A and deliver the result to onActivityResult(), just as if Activity A hadn’t died at all.
Note:
This is only possible if both of your activities are in different process. OS never kills activity directly when its under memory pressure. It simply kills the entire process hosting the activity. If both of your activities are hosted in same process then your scenario shouldn't happen.
Any callback class instances, member variables, and even static variables are destroyed along with Activity A, since whole process is killed.You have to re-create them in Activity A.

onStop vs onDestroy

I have tried to research exactly when the onDestroy method is called for an activity, but I've read some confusing and conflicting information. In general, my question is: under what circumstances is the onDestroy method actually called on an activity? More specifically, if I have two activities, activity A and activity B, if activity A is running and I create an intent and switch to activity B, is activity A only stopped, or is it destroyed?
Like stated in the official documentation:
onDestroy()
The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
In your example the Activity A is stopped and could be destroyed by the System
Note per documentation link above:
…do not count on [onDestroy()] being called as a place for saving data … [see] either onPause() or onSaveInstanceState(Bundle).
onDestroy() is called whenever:
The user takes out the activity from the "recent apps" screen.
The user takes out the activity from the "recent apps" screen.
onStop() is called whenever:
The user leaves the current activity.
So in your example, when the user launches Activity B, Activity A called onStop().
EDIT:
The onDestroy() method is not always being called, according to the documentation. onStop() is always called beginning with Honeycomb, so move code you explicitly need to do before the activity stops to there.
Starting with Honeycomb, an application is not in the killable state until its onStop() has returned.
https://developer.android.com/reference/android/app/Activity#ActivityLifecycle
Hope this helped :D

android: how to handle onStop method call

If I have a method called onStop and it calls super.onStop();. When does this method run?
In my main activity, I start another activity as follows: startActivity(new Intent(this, MyNewActivity.class));. Does this automatically stop my main activity and call onStop?
Also, what kind of things should I do in the onStop method of my main activity. So far all I have done is unregister listeners to free up space but other than that is there anything else I should do?
Thank you, any help is greatly appreciated.
When does this method run?
This method calls when your Activity is no longer visible to the user
Does this automatically stop my main activity and call onStop
Yes when you start another Activity first onPause() function get called and then onStop().
what kind of things should I do in the onStop method of my main activity
It depends on your implemenetation and your needs but persisting data recommended to implement on onPause() callback function
In my main activity, I start another activity as follows: startActivity(new Intent(this, MyNewActivity.class)); Does this automatically stop my main activity and call onStop?
You can know yourself what happens when you call new activity takes focus just put a simple log statement and check yourself.
http://developer.android.com/guide/components/tasks-and-back-stack.html
Quoting from the docs
When the current activity starts another, the new activity is pushed on the top of the stack and takes focus.
The previous activity remains in the stack, but is stopped. When an activity stops, the system retains the current state of its user interface. When the user presses the Back button, the current activity is popped from the top of the stack (the activity is destroyed) and the previous activity resumes (the previous state of its UI is restored).
onStop()
Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.
Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.
Check the topic saving activity state
http://developer.android.com/guide/components/tasks-and-back-stack.html#ActivityState
Note: When the system stops one of your activities (such as when a new activity starts or the task moves to the background), the system might destroy that activity completely if it needs to recover system memory. When this happens, information about the activity state is lost. I believe this happens on priority basis.
If you need to store persistent data do it in onPause
For more info check the activity lifecycle
http://developer.android.com/reference/android/app/Activity.html

abnormal behavior of parent activity after finishing child activity

I have Activity A and I am calling Activity B from Activity A using setResultForActivity.
Now in Activity B when I press Done button I am firing finish() and it returns to
Activity A and it return down to onActivityResult. Now the issue is after when I fired finish() in Activity B , Activity A's onCreate doesn't get called and thats why
some of the custom listeners in my ListView isn't working , it seems that they are not bind.
so the whole activity respond pretty weirdly , can anyone has solution to this ?
Why a fourth answer? Because in my view, the others aren't fully correct.
Truth is, Activity A could have been destroyed in the meantime, or not. This depends on whether Android needs memory or not. So it is possible that Activity A´s onCreate() is called (along with the other lifecycle callbacks), or not. In the latter case, onActivityResult() is called before onResume().
While for configuration changes, the most efficient way to preserve the Activity's state is via nonConfigurationState, if you want to prepare for a restart of your Activity after it has been destroyed, you can use the InstanceState mechanism, because while Android destroys your Activity A, it will keep its intent and saved instance state to re-crearte it.
This stresses the absolute necessity to place initialization exactly in the callback where it belongs.
To test whether your Activity logic works regardless of whether Android destroyed it or not, you can use the DevTools setting "Development Settings" -> "Immediately destroy activities". The DevTools app is available on AVDs and can also be downloaded from Google Play.
Just place your onCreate() stuff in onResume() of Activity A except setContentView().
Just have a read on Android Activity Lifecycle : http://developer.android.com/training/basics/activity-lifecycle/stopping.html. onCreate() is only called when the activity is first created. You can do your list thing in the onResume() method.
Activity A's onCreate won't get called because the activity has not been destroyed. When an Activity regains focus from another activity, it's onStart and onResume get called, so I would put your bound listeners in those. They will also be called when onCreate is normally called.
After your child activity is finished() it return to execute onActivityResult which is in your case in Activity A. The onCreate method is not supposed and does not get called when killing of you sub-activity, a.k.a Activity B.
Please post some source code for us to work on and I will improve my answer! :)

SavedInstantState created during onSaveInstanceState not restored in onCreate

My app an activity (which now a subclass on FragmentActivity, although I don't think that matters), let's call it Activity A.
In it, a button navigates away to (say) Activity B by starting it via Intent using startActivity() with no special flags.
Neither activity has any special flags (SingleTop) etc in the manifest, not calls finish() etc. i.e. nothing unusual.
Activity A's method onSaveInstanceState() get's called and I save some state info.
In Activity B I hit the BACK key and come back to Activity A.
It's onCreate() method is called, but the Bundle of "savedInstanceState" is null, and so I cannot reconstruct the state I had previously saved.
Any ideas what I am doing wrong, and how I can ensure I get the state back.
BTW: On a configuration change (say rotate), it all works fine....
It seems strange that onCreate() is getting called when you go back to Activity A just by pressing the back key. In general it should just show the existing activity without trying to recreate it. I also think it also strange that onSaveInstanceState() is getting called when you start the other activity. In fact, the documentation states that it probably won't call onSaveInstanceState() when starting Activity B:
An example: when onPause() is called and not
onSaveInstanceState(Bundle) is when activity B is launched in front of
activity A: the system may avoid calling onSaveInstanceState(Bundle)
on activity A if it isn't killed during the lifetime of B since the
state of the user interface of A will stay intact.
From here.
I think something else is going on.
Activity A was never destroyed, therefore onCreate() should not be called. Can you please put some code up?

Categories

Resources