I have an activity A which contains fragment F. A shows F by pushing it onto fragment manager's back stack. This fragment may show a dialog(more specifically, a DialogFragment) D, also by pushing it to the same fragment manager's back stack.
I need to be able to dismiss dialog D under certain circumstances that are determined by fragment F. Normally I would check if D is on the fragment manager's back stack and use getFragmentManager().popBackStack() to remove it. But this doesn't work if the activity gets destroyed and then recreated:
Say I set "Don't keep activities" flag in Android Settings. Now I background the app. Activity gets destroyed, and the fragments are too. Now I foreground the app again. At what point do the fragments F and D get added to fragment manager's back stack? This is a screenshot I took after I put a breakpoint on A's onPostResume() method, which I assume is the very last one to run in the activity lifecycle, before the user can use the app:
You may notice that mAdded field contains 2 elements - those are the restored fragments F and D. But they are not on the back stack yet, as mBackStack is null!
I would like to be able to remove D, but Android won't let me do it, since it's waiting to restore pre-existing state of fragments and it won't add them to the back stack until some time after onPostResume.
So in essence, I can't remove the fragment from the stack, since it's not on the stack yet. And I also can't prevent it from being added to the stack at some point, since, as you can see from the screenshot above, fragment manager stores it in a separate list mAdded and there's no methods that I can use to remove it from mAdded.
How can I prevent a saved fragment from being restored?
Maybe Im wrong but AFAIK AOS doesn't store the fragment backstack at all if activity stops. It could only restore the last shown fragment without all the previous fragments on a stack.
However you could store the stack and fragments state yourself. Just remove your dialog in
onPause
storing some flag viaonSaveInstanceState
and then inonResume
restore it or don't.