java – Does a fragment get destroyed when you pop the back stack?-ThrowExceptions

Exception or error:

Cannot find a direct answer to this so i’ll ask here.

If I have one activity which starts with Fragment A attached and then when a button on A is pressed it replaces fragment A with fragment B. A is added to back stack. If the back button is pressed it will go from B back to A but I want to know does the fragment B get destroyed? because technically the activity is not so do I need to explicitly remove fragment B even when the back stack is pop?

Thank you for reading

How to solve:

According to the Android API, it is destroyed, it is stopped.
http://developer.android.com/guide/components/fragments.html#Lifecycle

Handling The Fragment Lifecycle

The most significant difference in lifecycle between an activity and a fragment is how one is stored in its respective back stack. An activity is placed into a back stack of activities that’s managed by the system when it’s stopped, by default (so that the user can navigate back to it with the Back button, as discussed in Tasks and Back Stack). However, a fragment is placed into a back stack managed by the host activity only when you explicitly request that the instance be saved by calling addToBackStack() during a transaction that removes the fragment.

Thanks Syed Ahmed Jamil, see his comment below.

###

Nope, it is not destroyed, its stopped

its states go like this
(while interacting)
1.) onAttach(Activity) called once the fragment is associated with its activity.
2.) onCreate(Bundle) called to do initial creation of the fragment.
3.) onCreateView(LayoutInflater, ViewGroup, Bundle)
4.) onActivityCreated(Bundle)
5.) onViewStateRestored(Bundle)
6.) onStart()
7.) onResume()

while not interacting
1.) onPause()
2.) onStop()
3.) onDestroyView()
4.) onDestroy()
5.)onDetach()

###

One back stack of fragment manager means one fragments operation you planed.
FragmentManagerImpl holds a field “mBackStack” deals with such thing.

According to Android API:

“… Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.”

Let’s see what happens in Activity.onBackPressed():

/**
 * Called when the activity has detected the user's press of the back
 * key.  The default implementation simply finishes the current activity,
 * but you can override this to do whatever you want.
 */
public void onBackPressed() {
    if (mActionBar != null && mActionBar.collapseActionView()) {
        return;
    }

    FragmentManager fragmentManager = mFragments.getFragmentManager();

    if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
        finishAfterTransition();
    }
}

If the activity is instance of FragmentActivity, the fields “final FragmentController mFragments” holding an instance of FragmentManagerImpl would call to popBackStackImmediate().

popBackStackImmediate() removes the top one of “mBackStack” and adds it to the “mTmpRecords”, a executing used back stack buffer, and marks “mTmpIsPop” that it needed to operate as pop out action.

What does “is pop” mean?
It means the your fragments operations recorded in this one back stack will be executed reversely.

To see executeOps() and executePopOps() of BackStackRecord to find out more:

void executeOps() {
    final int numOps = mOps.size();
    for (int opNum = 0; opNum < numOps; opNum++) {
        final Op op = mOps.get(opNum);
        final Fragment f = op.fragment;
        if (f != null) {
            f.setNextTransition(mTransition, mTransitionStyle);
        }
        switch (op.cmd) {
            case OP_ADD:
                f.setNextAnim(op.enterAnim);
                mManager.addFragment(f, false);
                break;

and

void executePopOps(boolean moveToState) {
    for (int opNum = mOps.size() - 1; opNum >= 0; opNum--) {
        final Op op = mOps.get(opNum);
        Fragment f = op.fragment;
        if (f != null) {
            f.setNextTransition(FragmentManagerImpl.reverseTransit(mTransition),
                    mTransitionStyle);
        }
        switch (op.cmd) {
            case OP_ADD:
                f.setNextAnim(op.popExitAnim);
                mManager.removeFragment(f);
                break;

Firstly you create a back stack after beginTransaction(), then add several fragments operation after add(), remove(), …, and commit() it. FragmentManagerImpl will execute your fragments plan by calling its executeOps()
So maybe you can see fragment A is hided, fragment B shows as your plan on screen.

In the case you press the back button, activity callback function calls to popBackStackImmediate(), FragmentManagerImpl will execute reversely your fragments plan by calling its executePopOps().
So maybe you can see fragment A shows, fragment B is hided as a back button action instinctively.

Leave a Reply

Your email address will not be published. Required fields are marked *