In our app we have an Activity with a FrameLayout. This layout shows several Fragments. To change between the Fragments we use the following method:
public static void replaceFragment(FragmentManager manager, Fragment fragment, boolean addToBackStack)
{
FragmentTransaction transaction = manager.beginTransaction();
Fragment currentFragment = manager.findFragmentById(R.id.container);
if (currentFragment != null)
{
transaction.remove(currentFragment);
if (addToBackStack)
{
transaction.addToBackStack(currentFragment.getClass().getName());
}
}
transaction.add(R.id.container, fragment);
transaction.commit();
}
If the fragment is changed with that method everything will work fine. Unfortunately the problem is that the back button seems to be broken.If we push it at one of these Fragments the FrameLayout will be updated correctly. But the Fragment won’t be destroyed. Android doesn’t call the onPause(), the onStop() and the OnDestroyView() methods. Therefore the action bar isn’t updated correctly. It’s still showing the menu items from that fragment. The disturbing thing about this is, that this behavior is just from one special fragment. Every other fragment works fine.
One interesting thing happens after pressing the standby button because after this interaction all missed onPause() and onStop() commands from the fragment are called at once.
EDIT:
I’ll explain the structure of the project. Maybe that helps. There’s an android.support.v7.app.ActionBarActivity with a DrawerLayout containing the FrameLayout and a NavigationDrawerFragment. The FrameLayout is used to show the Fragment related to this app. With a click at a navigation drawer item the fragment which is shown in the FrameLayout changes. With a click at the back button the HomeFragment which is the start fragment is called from the back stack (just this fragment is added to the back stack). It workes from every fragment with the exception of our quiz. The quiz contains several states. The navigation drawer item quiz links to a selector fragment which reads the current state of the quiz and forwards to the quiz fragment which shall be shown (related to the state). just when I click the back button from that fragment the HomeFragment is shown correctly but the fragment isn’t removed. It’s still in the resumed state. Did someone know how to solve this problem?
EDIT 2:
I build a minimal app to test the behaviors. I did it step by step to find my mistake. To test it I added logs for every important method. My results are below.
Szenario 1: add forwarder fragment to back stack
App starts (home fragment is opened):
07-03 09:20:42.939 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onAttach 07-03 09:20:42.939 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onCreate 07-03 09:20:42.939 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onCreateView 07-03 09:20:43.039 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onStart 07-03 09:20:43.069 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onResume
open forwarder fragment which forwards to test fragment (add home fragment to back stack)
07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onAttach 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onCreate 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onCreateView 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onStart 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onResume 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onPause 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onStop 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDestroyView 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onAttach 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onCreate 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onCreateView 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onStart 07-03 09:21:42.572 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onResume
click at back button (back to forwarder because it was added to back stack)
07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onPause 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onStop 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onDestroyView 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onDestroy 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/TestFragent? onDetach 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onCreateView 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onStart 07-03 09:22:53.538 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onResume
click at back button (back to home)
07-03 09:23:18.755 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onPause 07-03 09:23:18.755 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onStop 07-03 09:23:18.755 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDestroyView 07-03 09:23:18.755 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDestroy 07-03 09:23:18.755 16461-16461/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDetach 07-03 09:23:18.755 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onCreateView 07-03 09:23:18.795 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onStart 07-03 09:23:18.795 16461-16461/de.hsanhalt.studiappkoethen D/HomeFragment? onResume
click at power button
07-03 09:29:52.495 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onPause 07-03 09:29:52.505 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onStop
The log means that everything will work fine if the forwarder is added to the back stack!
Szenario 2: don't add forwarder fragment to backstack
App starts (home fragment is opened):
07-03 09:28:00.435 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onAttach 07-03 09:28:00.435 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onCreate 07-03 09:28:00.435 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onCreateView 07-03 09:28:00.536 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onStart 07-03 09:28:00.566 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onResume
open forwarder fragment (add home fragment to back stack)
07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onPause 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onStop 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onDestroyView 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onAttach 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onCreate 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onCreateView 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onStart 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onResume 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onPause 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onStop 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDestroyView 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onAttach 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onCreate 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onCreateView 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onStart 07-03 09:28:59.058 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onResume
click at back button (back to home because forwarder wasn't added to back stack)
07-03 09:29:28.990 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDestroy 07-03 09:29:28.990 18158-18158/de.hsanhalt.studiappkoethen D/ForwarderTestFragment? onDetach 07-03 09:29:28.990 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onCreateView 07-03 09:29:29.030 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onStart 07-03 09:29:29.030 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onResume
click at power button
07-03 09:29:52.495 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onPause 07-03 09:29:52.495 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onPause 07-03 09:29:52.505 18158-18158/de.hsanhalt.studiappkoethen D/HomeFragment? onStop 07-03 09:29:52.505 18158-18158/de.hsanhalt.studiappkoethen D/TestFragent? onStop
The error will occur!
result
The logs told me that the error just happens when the forwarder fragment isn't added to back stack. Does somebody know why there is this difference in the lifecycle?
I think I've to manipulate the back stack in the test fragment. I could pop it so that the forwarder isn't at the top of the back stack anymore. I'll give it a try.