Is there a method of the Activity lifecycle that is guaranteed to get called when my app crashes?
I put logs in all methods and crashed my app but I didn't see anything.
I couldn't find anything in the docs too.
I basically want to save changes in a database but ideally I do not want to do it in every update but rather in a method like onPause or onStop etc.
None of the lifecycle methods will be called if your Activity crashes.
However, for child activities started using startActivityForResult you do get a RESULT_CANCELED code returned in onActivityResult on the parent Activity.
Related
Long story short: I am currently working on a small android game. One feature is being able to change the app theme. When the user changes the theme, an event is broadcasted throughout the app and all active activities call recreate() to apply the new theme.
The problem:
Let's say there is a stack of activities: A, B, C. All activities will receive the event in the order they were opened and call recreate(). These are the lifecycle events that will get called (in order):
Activity A will call onDestroy(), onCreate(), onStart(), onResume() and onPause()
Activity B will call onDestroy(), onCreate(), onStart(), onResume() and onPause()
Activity C will call onPause(), onStop(), onDestroy(), onCreate(), onStart(), onResume().
Note that neither activity A or B called onStop(). When those activities are being returned to (eg. back button press), they will not call onStart() when they become visible, but will call onResume(). This is contrary to what is stated in the activity lifecycle documentation.
The question: Is there something I'm doing wrong here? Is there another way to restart all activities in an application without messing up the activity lifecycle?
I think you are taking the wrong approach here. You should not use the framework calls in order to change your theme. The issue you are having is that you are not calling onStop as the framework would, but even so...
The primary reason your approach is incorrect is that Android may have already destroyed an Activity if it is not visible. So sending events to it that call framework methods is not only unnecessary at that point, but it could result in unpredictable states and behavior. Could even cause a crash.
For changes to your theme or any UI component, you should handle that in onResume - in other words handle changes to the UI elements when the user returns to the Activity. One option for doing this is passing flags through startActivityForResult.
Better, make your theme selection persist using sharedPreferences (or using another method) and then read from that when the Activity is resumed. This would ensure the proper theme is selected regardless of how the user gets to the Activity.
EDIT:
Note that the Activity framework methods are public not because they should be accessed at any time or by other classes, but because that is required for them to be implemented in your app. They are not intended to be invoked outside the framework.
You should note that in the official documentation for Activity none of the methods you are calling are listed as "Public Methods" (http://developer.android.com/reference/android/app/Activity.html#Activity()). You are using them in an unsupported way. However, I only point this out to make you aware of it and that it is not a generally accepted approach to solving this problem.
This is exactly in line with the documentation.
http://developer.android.com/training/basics/activity-lifecycle/starting.html
If you look at the chart, onResume gets called when returning to an activity no matter what but onStart doesn't.
if you want to change UI related component then you must use OnResume method instead of recreating all activities. like following.
#override
onResume()
{
textview.setText("Change text When activity resumes");
}
Colleagues above responded very well.
The behavior you reported. The onstart and onResume not be called. I've watched it happening to Hot Code Swapping. It is worth stopping the application and call the rebuild.
I am facing some problems so as a conclusion can I get how to know current Activity is finished or not in onSavedInstanceState() ?
Is there any possible solutions then let me know.
In your Activity, you can call isFinishing() (which can tell you if the Activity is in the process of finishing) or isDestroyed() (which can tell you if the Activity is invalid). Please note that isDestroyed can only be called if you are using API 17 or above.
For the official references, you can see here: http://developer.android.com/reference/android/app/Activity.html#isDestroyed()
http://developer.android.com/reference/android/app/Activity.html#isFinishing()
Check for onDestroy() Method, if its gets called or not.
According to android docs
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.
If your onDestroy method of activity gets called your activity will be finished and no instance will be saved in the back stack.
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 Activity, I register receiver in onCreate and unregister it onDestroy. It should works fine if every onCreate is followed by onDestroy after the next onCreate. Otherwise, if onCreate is being called more than onDestroy, receiver is registered multiple time and the app mis-behaves.
So my questions are:
Is that ok I register receiver in onCreate and unregister it in onDestroy?
Is that onCreate is always followed by onDestroy before next onCreate?
onDestroy is not guaranteed to be called:
http://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29
"
protected void onDestroy ()
Added in API level 1
Perform any final cleanup before an 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.
Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running. There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.
Derived classes must call through to the super class's implementation of this method. If they do not, an exception will be thrown.
"
You may also want to look at this thread:
Activity OnDestroy never called?
onDestroy is called when the activity is being destroyed. Or removed from the back stack, when ever the user doesn't want it or there is no possible way to get back to it. When your activity wants to receive a broadcast that is fine to do it how you are. If there are no dialogs appearing or notifications or toasts appearing after you receive that should be fine also, if you want to be on the real safe side and only have one activity receiving at a time, and only while the activity is visible move these to onResume and onPause.
You could probably some how unregister when another activity has been brought to the front and re-register after?
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