I think my ideas on activity lifecycle and bundles
are a little confused,can you help me?
Let's suppose the user opens activity A from home screen,
activity A "calls" activity B which fills the screen.
On this event onSaveInstanceState() is called on activity A then onPause() and onStop().
Since there are too many apps currently running on the system,
andorid decides to kill the process hosting activity A.
When the user navigates back to activity A,onCreate() is called an we can
use the bundle ( setted during the last call of onSaveInstaceStae() ) to restore the state.
then onStart(),onRestoreInsanceState()
and onResume() are called,
am I right?
Then lets suppose the user presses back key to exit from activity A
onPause(),onStop() and onDestory() are called in sequence on activity A (the call of onDestroy() could be postponed though)
onSaveInsanceState() should not be called in this scenario.
When the user opens again activity A later on then the bundle
passed to onCreate() is null,right?
Now Suppose the user rotates screen
onSaveInsanceState() ,OnPause() ,OnStop(), OnDestroy() are called
then onCreate() with bundle setted by the last call to onSaveInsanceState(),
and then onStart(), and onRestore().
am I right?
My guess is that:
when the user creates an ativity,the bundle passed to onCreate() is always null and onRestoreState() is never called,but when the system creates it , for instance when it killed the activity because of low memory or because of a rotation event,the bundle passed is the one setted by the last call of onSaveInstanceState().
Is my guess right?
thanks and sorry for my poor english.
P.S. : I think onRestoreInstanceState() is passed the same bundle is passed onCreate() but typically state is restored using onCreate().
Interesting question - never thought about it.
Take a look at the documentation, onCreate() and onSaveInstanceState().
This answers at least your question what Bundle will be supplied to onCreate().
Unfortunately there is no exact definition on which events onSaveInstanceState() is called, but I guess it is called by default in all relevant situations (whatever they may be...), but you can find out for some situations (e.g. rotating the screen) by putting a Log.i() to LogCat.
onRestoreInstanceState() is passed the same bundle is passed onCreate() is right, and the system restart the activity by call onCreate() and also call onRestoreInstanceState(),the bundle will be null if get from onCreate() when the activity first started.
Since there are too many apps currently running on the system,
andorid decides to kill the process hosting activity A.
This is a very common situation. Furthermore - you can emulate this action using developers option.
In this case each activity, that was move into background, will be automatically destroyed.
About Bundle in OnCreate .
I can get from my memory only two cases when OnCreate will be called with non-null Bundle. First - described above. Second case - screen rotation.
When you launch app Android calles
onCreate
onStart
onResume
After that lets doing screen rotation. Android will call
onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
The more information you can find on topic about recreating
Related
In the Activity Lifecycle diagram there's an arrow from 'onStop' to 'App process killed' to 'onCreate'. I've always wondered, and now I'm going to give a small talk on fragments; How is it possible for onCreate to receive the bundle from onStop if the whole app process is destroyed? Does the system keep track of killed apps and their activity bundles? I think that would be how it would do it because at that point the killed application would have zero memory allocated to it.
Also, from the last paragraph on the page Managing the Activity Lifecycle>Starting an Activity, "The system calls onDestroy() after it has already called onPause() and onStop() in all situations except one:...' And that one situation isn't stated as being low on memory. This makes me think that the arrow should never go from onStop to onCreate because of 'Apps with higher priority need memory'. Is this a typo or am I reading it wrong? I assume I'm reading it wrong because of the 'Killable?' column in 'in general the movement through an activity's lifecycle looks like this:' chart.
One of these has to be wrong either the arrow in the activity lifecycle chart or the "The system calls onDestroy() after it has already called onPause() and onStop() in all situations except one:..." statement. Hopefully I'm reading out of context.
How is it possible for onCreate to receive the bundle from onStop if the whole app process is destroyed?
It doesn't "receive the bundle from onStop", insofar as onStop() has nothing to do with a Bundle. The Bundle delivered to onCreate() and onRestoreInstanceState() contains the data put in an earlier Bundle by onSaveInstanceState(). The content of that Bundle is passed across process boundaries to a core OS process that manages the state of outstanding activities and their tasks. That content is passed back to the fresh process for your app if and when it is relevant.
Does the system keep track of killed apps and their activity bundles?
The OS keeps track of outstanding tasks. For a while (~30 minutes since last use), it keeps track of the instance state Bundle for the activities on the task.
The system calls onDestroy() after it has already called onPause() and onStop() in all situations except one
There is more than one situation in which onDestroy() is not called. Terminating the process due to low memory conditions may or may not result in onDestroy() being called, depending on the urgency of the need for system RAM.
It is very possible for onCreate to be called after onStop(). You pass bundles using onSaveInstanceState() which is called anytime the activity or fragment pauses or stops. Say you have an activity and press home. OnStop and onSaveInstanceState are both called. In onSaveInstanceState you save your bundle to save the state of the app. The app is then killed because it was in the background for too long. Then when you open the app back up the bundle from onSaveInstanceState is passed to oncreate in the SavedInstanceState parameter when ever it gets recreated. See the official docs for more https://developer.android.com/training/basics/activity-lifecycle/recreating.html
I read the Android documentation and I don't understand one step:
When I press a button my app shows the Activity2 with the startActivity(intent) method, then I use the back button and my app shows the Activity1 again. If I want show the Activity2 I press the button again, and my app always call onCreate to the Activity2.
The Android documentation says the method onCreate is called only when is starting or when is destroyed.
Why is this happening?
Thanks!!
Regars.
The OnCreate() method is called each time the activity is displayed (created). So each time you call the startActivity(intent) method, the OnCreate method will be called.
Check the Activity Lifecycle for more information.
It's because you pressed the back button when you were in Activity2, which by default destroys the activity you're currently on. You can override onDestroy() and print a debug message to confirm (make sure to call super).
Instead of retaining the same Activity2 object, you should leverage onSaveInstanceState(Bundle) and onRestoreInstanceState(Bundle) to save and restore your Activity2's state, respectively.
Technically you could use the Bundle object passed into onCreate(Bundle) as they are the same object. The docs recommend onRestoreInstanceState(Bundle):
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.
It's completely normal beheviour. You are calling startActivity() so activity is starting. That's all. This method is called also when you are changing configuration - i.e rotating the device. Moreover - it's also possible that Activity1.onCreate() will be called after pressing back button, while it's going background and can be disposed by system if more ram is needed.
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! :)
In my app, when user presses HOME key and returns back to app after some time, my app gives NullPointerExceptions on various places and activities. I know that my app is being killed by OS to free some resources. Now I want that when user comes back again to app and app was previously killed, then how can I detect that my app was killed so that I can reload different resources?
When onCreate (Bundle savedInstanceState) is called, check that savedInstanceState is not null. As stated by onCreate :
savedInstanceState If the activity is being re-initialized after
previously being shut down then this Bundle contains the data it most
recently supplied in onSaveInstanceState(Bundle). Note: Otherwise it
is null.
See also onSaveInstanceState() which is not part of the normal lifecycle but is called before the activity is killed.
Note : if the user does A ----> B ----> C --back--> B ----> C, the second time C is created the passed bundle will be null, as it is a new instance, not the same recreated after being killed.
Basically: look at the picture on this page: http://developer.android.com/reference/android/app/Activity.html
the various functions that are called in different situations are onCreate, onStart and onResume.
My suggestion would be: implement your own Application and if the onCreate() is called, the app was killed in background
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?