1

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.

boeserwolf91
  • 166
  • 1
  • 7

1 Answers1

2

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.

fragments life cycle

read this check this

Sush
  • 3,864
  • 2
  • 17
  • 35
  • I read it. Have a look at the picture in the "Creating a Fragment" section. If one clicks at the back button to enter the last fragment the app will call the onPause, onStop and onDestroyView methods of the current fragment and will go back to the onCreateView method of the old fragment.. This lifecycle works normaly. But it doesn't work at the one special fragment. I don't know why. :( – boeserwolf91 Jul 01 '14 at 18:39
  • read this http://developer.android.com/guide/components/activities.html#Lifecycle – Sush Jul 01 '14 at 18:41
  • Thank you, but that didn't help me :( I edited my description. Maybe that makes my problem a little clearer. – boeserwolf91 Jul 01 '14 at 19:52
  • then please check what are the implementation difference in fragments. i mean in terms of are you adding, attaching or replacing. if non of things works then try to achieve from other call backs on in the fragments. At last if non of the things works for you implement your your own cal baskcs – Sush Jul 02 '14 at 06:01
  • I edited my description. I think I'm at the way to solve it. At least I hope it :) – boeserwolf91 Jul 03 '14 at 07:50
  • 1
    This sentence is wrong! " You wont get any call back for fragment's 'onPause' until activity 'onPause' method is been called. ". The correct is :" You won't get any call back for activity 'onPause' until fragment 'onPause' method is been called." – Milad Yarmohammadi Feb 07 '18 at 06:20
  • MilaDroid tanks – Sush May 30 '21 at 10:11