Reputation: 176
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.
Upvotes: 1
Views: 2009
Reputation: 3874
The behavior is perfectly fine. Life cycle of fragments is completely tied to life of activity.
onStart
, onPause
,onStop
all the methods will be called based on activity lifecycle similar methods. You won't get any call back for fragment 'onPause' until activity 'onPause' method is been called. Please read android fragments documentation.
Fragment is not activity, its just like any other view or widget but its has some callback methods from activity, which makes it different than view.
read this check this
Upvotes: 2