In part of my Activity's code, I am calling Activity.finish() to close my activity, and the application returns to the main OS "desktop" window.
However, if I click on my application icon again, onCreate does not seem to be called and my view remains the same as when finish was called.
Perhaps, I'm not understanding the lifecycle correctly, but I thought that destroy completely destroyed the activity, and the next time it was invoked it would call onCreate.
Where am I misunderstanding this?
Thanks
In part of my Activity's code, I am calling Activity.finish() to close
my activity, and the application returns to the main OS "desktop"
window.
However, if I click on my application icon again, onCreate does not
seem to be called (...)
Yes, it is called. Just Log.d and you'll see.
and my view remains the same as when finish was
called.
It may remain the same because the XML content and all views instantiated are again created. However, if you modify stuff and layouts in code you'd see that it is restored to the defaults as in setContentView(int layout).
Perhaps, I'm not understanding the lifecycle correctly, but I thought that destroy completely destroyed the activity, and the next time it was invoked it would call onCreate.
As I said, it calls.
Related
This is how I'm launching my activity:
Intent intent = new Intent(Quotr.this, AddQuote.class);
startActivityForResult(intent, ADD_QUOTE_REQUEST);
And that activity finishes with a call to finish()
But I've been having issues with my onCreate() and onDestroy() methods being in the main activity (defined in Quotr.class) being called when I don't want them to. I added calls to Log.v() in both of those methods to see what was being called and when, and oddly, when the activity is launched, onCreate() of the main activity is called, and when the new activity is finished, the main activity's onDestroy() method is called.
This is causing a ton of issues, and I don't even know how to work around it at this point, because all my cleanup in main activity's onDestroy (which I only expect to be run when the activity is ACTUALLY recreated, not every time this new activity is launched) is being called while the activity is still in use.
Oddly enough, this only happens with this particular activity. As far as I know, I'm calling and finishing all my other activity intents in the exact same way, but they don't mess with the main activity's life cycle like this AddQuote.class one does.
I'm really at a loss for what else I can check at this point. I've checked for anything wrong in the manifest, I've checked I understand activity lifecycles, but this really makes no sense.
Oh my god, so I'm a huge idiot.
I'm working on an app that's been slowly built up over the course of a year and a half, and it was my first ever attempt at an app. For some reason, for the first new activity I made in the app (the one I was having an issue with), I was extending the main activity instead of AppCompat activity. So my calls to super.onCreate() and super.onDestroy() were calling back to the main activity, because THAT'S the super class.
I'll leave this up anyway in the off chance someone makes this mistake as well. Hopefully it helps someone.
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.
When I start my android-activity first onCreate() is called, then onResume().
When I then press the back-button to return to the home-screen and tap the app-icon again, first onCreate() is called, then onResume() and then onDestroy().
My app is still active then, but doing some action result in error since onDestroy() sets a few members to null.
Why is that?
Update: When I wait 30 seconds after pressing back everything works fine. I'm not doing anything heavy in onDestroy except setting a few variables to null and .interrupt()ing a background-thread.
Figured this out by myself. My understanding of what an Activity is was flawed. Of course Android calls onDestroy() on the old Activity instance, which can happen several seconds after the new one has been constructed.
onDestroy gets called because, by default, pressing back key results in your activity calling finish() which initiates the destroying of the activity which calls onDestroy().
To prevent doing some action in case the activity is being destroyed do like this:
if(!isFinishing()) {
// do your action here
}
isFinishing is a method of the Activity.
are you doing some heavy operations in onDestroy(). I think your activity view is destroyed, but not the activity object. And you tap on the App icon even before the previous Activity object is actually destroyed.
I think there is something in addition to what you are describing. Android doesn't just keep activity from being destroyed, something MUST be happening on the main thread.
The symptoms sound exactly as if you had either:
a service doing a longish HTTP or database operation. Are you sure there are no suxg things?
another thread (perhaps managed by an AsyncTask?) calling a synchronized method
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! :)
I don't know if these are related yet, but I have an app that won't let me click one of the buttons after resuming from onDestroy()
is this a known issue? the listeners are set onCreate()
and never set to null
onDestroy is the end of the life cycle for an activity. This means that the next time your activity is opened it is not "resumed" it is being created. This may be a bit confusing because even though the activity is being recreated onResume is still called. You might want to take a look at the activity lifecycle for a better description of what is actually happening as your activity moves through the different activity states.