My activity A starts one activity B in another app, and the user can spend quite some time on that activity. During this time, Android could possibly destroy my activity A (perhaps to reclaim memory), I am wondering:
If A starts B with startActivityForResult, and B calls setResult to return to A, If A needs to be recreated, will onActivityResult get called after A's onCreate?
If A starts B with startActivity, and B return to A by calling startActivity with flag FLAG_ACTIVITY_SINGLE_TOP, if A is alive, onNewIntent should be called. But if A is destroyed, will onNewIntent get called after onCreate?
I have read about android activity lifecycle posts on SO, but am not sure about this. And it's not easy to experiment on this.
1)It will, but the order of lifecycle calls may be a bit different than you expect. Be prepared for that possibility.
Related
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.
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.
My activity calls an activity in another app for result. Now, while the called activity is running, there's a chance that my process will be quietly killed for lack of memory. If that happens, once the called activity finishes, the caller activity (mine) will be revived and onActivityResult() will be invoked some time after onCreate().
Question - in activity's onCreate, is there a way to tell if this is the case, or the caller activity is being invoked in the regular way?
If the other app returns a result code, then you can check for that in the onActivityResult. If the result code is different to what you expect, then you can assume that the activity did not finish correctly, i.e it was killed.
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?
In my Activity onCreate method I create and Intent (say to launch the camera) and call startActivityForResult. The problem is that onCreate is called twice and the Intent is launched twice. Both are received in onActivityResult.
What is going on here? How should I automatically launch an Intent when my Activity loads? I tried calling startActivityForResult in onStart, but it is still called twice.
Thanks.
onCreate is normally called when you return from another activity, like in your example. The activity lifecycle docs by Google are a bit misleading in this respect (they make you think onCreate only called once during the app lifecycle).
Your best bet is to save your state in onSaveInstanceState, e.g. add a cameraCalled flag, and then check that flag in onCreate to prevent a loop.
onCreate may and may not be called when you are returning.
It will depend on memory situation and whether or not OS killed your activity. You will need to account for both scenarios. It is probably not doable when you call from onCreate. See this for more information on order of what is called on the return State of Activity while in onActivityResult question