Possibility of not calling Activity.onResume() - android

My app does a lot of setting up in onCreate and then in onResume.
Is it possible that if a device rotation occurs while onCreate is being performed then onResume won't be called?
I'm asking because I receive many crash logs happening in onPause(). The crashes occur, because in onResume() I ALWAYS register some listeners and in onPause they are ALWAYS unregistered. Exception is thrown when a listener that hasn't been registered is unregistered.
So: is it possible that onResume() is not called at all before onPause()?

is it possible that onResume() is not called at all before onPause()?
No. Never.
onResume() Called just before the activity starts interacting with the user. At this point the activity is at the top of the activity stack, with user input going to it.
Always followed by onPause(). So if onPause() of an Activity is being called means onResume() must called.
Read A summary of the activity lifecycle's callback methods for more details.

Is it possible that if a device rotation occurs while onCreate is being performed then onResume won't be called?
Yes possibly, although it seems highly unlikely. Even if you are doing a lot of stuff in onCreate in relative terms you should never be doing so much that it takes several seconds. In other words, for a user to start your Activity and then rotate the device is going to take some finite 'human reaction' time.
If you believe this is happening then...
Reduce the amount of stuff going on in onCreate
NEVER assume that your listeners are registered - check first. Example, when you register a listener set a boolean and only unregister if it's true and set the boolean to false...
Psuedo code:
// To register
if (!isListenerRegistered) {
register(...);
isListenerRegistered = true;
}
// To unregister
if (isListenerRegistered) {
unregister(...);
isListenerRegistered = false;
}

No, http://developer.android.com/training/basics/activity-lifecycle/pausing.html
the sequence is always onCreate(), onStart(), onResume(), then the user sees the activity in the foreground(totally visible). Once another activity starts, this one goes to onPause(), then onStop().
When the device is rotated the activity gets reloaded, so it goes through the destruction steps depending on when the rotation occured. After onDestroy() is called, the creation starts again with onCreate(). Add log messages in your callbacks to see this:
Log.d("DEBUG", "In Activity A's onCreate()");
You can filter your logcat via the log tag, in this case "DEBUG" and see the lifecycle for yourself. Or just step through with the debugger.

Related

how to know when activity is destroyed due to orientation change?

I am making an Activity that logs a message when the activity is destroyed due to orientation change.
What I want to do is to call that Log.d() UPON the moment the activity is destroyed.
In other words, I don't want to call it by checking savedInstanceState==null after the activity is recreated.
Is there a way to know why the activity is destroyed before I reach onDestroy()? Thanks
You can use isChangingConfigurations() from the docs:
Check to see whether this activity is in the process of being destroyed in order to be recreated with a new configuration.
Docs available here
If I understood correctly you want to log something before destroying activity.
According to the lyfecyle activity diagram you should do that at this point.
In your activity maybe you have to overwrite onDestroy method and call log before the super call.
#Override
public void onDestroy() {
//log
Log.d()
super.onDestroy();
}
EDIT:
Juan is right, as the docs mentions:
"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."
https://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29

activity finishes itself but onDestroy() call for this activity happen so late

I found a bug in our code that we are launching the activity(let's call this as SCREEN_ACTIVITY) by
Intent intent = new Intent(SharedIntents.INTENT_SCREEN);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
Android documentation : When using FLAG_ACTIVITY_NEW_TASK, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in.
So everything works fine in most of the case.
That screen activity will call finish() when user click something. Also this screen activity will get launch or create by incoming event from the service.
6053 I/ScreenActivity(15395): onCreate
6682 E/ScreenActivity(15395): finish() Activity
6832 I/ScreenActivity(15395): onDestroy
7284 I/ScreenActivity(15395): onCreate
7911 E/ScreenActivity(15395): finish() Activity
8063 I/ScreenActivity(15395): onDestroy
10555 I/ScreenActivity(15395): onCreate
13413 E/ScreenActivity(15395): finish() Activity
13701 I/ScreenActivity(15395): onCreate
13799 I/ScreenActivity(15395): onDestroy
The last one is the issue. ScreenActivity is created and then call finish() itself. But the problem is that onDestroy is being called very late. Before that there is incoming event from the server and calling startActivity() trigger a new ScreenAcitivty onCreate(). The problem is that ScreenManager class keeps flags for that activity created and destroyed.
The flag is set when onCreate() callback and onDestroy() callback.
So for line 10555 and 13701 the ScreenManager set createFlag = true. for line 13799 set createFlag = false.
The event comes after line 13799 will assume that the activity is not created and events are not notified to the activity.
Hope my description for the issue is clear to you.
Is this kind of scenario onStop() and onDestroy() call so late after calling finish() is expected to happen? If yes, i have to think about the solution.
If not, then is there any places to modify?
Thanks a lot.
onDestroy() may or may not be called. You cannot rely on it being called all the time. From the docs:
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.
If you need to know that your Activity is finishing, a reliable way to know if it is finishing is the isFinishing() method. You can call it in onPause() to find out if this pause will eventually lead to this Activity being destroyed:
#Override
protected void onPause() {
super.onPause();
if (isFinishing()) {
// Here you can be sure the Activity will be destroyed eventually
}
}
use Handler,
new Handler().postDelayed(new Runnable() {
#Override
public void run()
//enter code here for open an Activity
}
},300);
after that, we are getting log should be:
onCreate
onStop
onDestroy
onCreate

android activity lifecycle callbacks and states

Please, help me understand activity lyfecycle more deeply. http://developer.android.com/guide/components/activities.html#ImplementingLifecycleCallbacks
They say:
The foreground lifetime of an activity happens between the call to
onResume() and the call to onPause().
Does this mean, that activity becomes resumed in some moment after onResume() is called, or after onResume() completely finished it's work?
Similar question about visible state and onStart.
And if the second is right (method completely finished it's work), then super.method() or overriden by me in activity class?
#Override
protected void onResume() {
super.onResume();
// is it now "resumed" after super.onResume()?
}
"The foreground lifetime of an activity" referes to the time it is directly being shown to the user. It also implies at the moment its process has maximun priority on the Android process priority ladder. You should read this http://developer.android.com/guide/components/processes-and-threads.html
Furthermore, onResume(), onPause()... are just hooks where you should insert code that needs to be executed on that specific moment of the activity lifcycle.
The foreground lifetime of an activity happens between the call to onResume() and the call to onPause().
Does this mean, that activity becomes resumed in some moment after onResume() is called, or after onResume() completely finished it's work?
Technically speaking, the Activity is in a state of being resumed before onResume() is called but the option for you to override the onResume() method allows you to fine-tune what needs to be done before the Activity enters the 'running' state. In other words, from the point of view of the OS, the Activity is resumed, then onResume() is called and, finally, from the point of view of your own individual app, resuming the Activity is complete when onResume() is complete and the Activity is running.
Similar question about visible state and onStart. And if the second is right (method completely finished it's work), then super.method() or overriden by me in activity class?
Again, the same logic applies - the OS goes through what it needs to do to start the Activity then calls onStart() for you to customise the starting stage of your Activity. The OS considers the Activity to have started before it calls onStart() but from your app's perspective, it hasn't completely become started until any code you have in your overridden onStart() method.

Why is onDestroy() called after onResume() when using back-button

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

Is that possible onCreate is called more than onDestroy in Android?

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?

Categories

Resources