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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With