Fragment already added IllegalStateException

AndroidAndroid 3.0-HoneycombAndroid FragmentsFragmentIllegalstateexception

Android Problem Overview


I use this method on my container Activity to show a BFrag

public void showBFrag()
{
    // Start a new FragmentTransaction
    FragmentTransaction fragmentTransaction = mFragmentMgr.beginTransaction();

    if(mBFrag.isAdded())
    {
        Log.d(LOG_TAG, "Show() BFrag");
        fragmentTransaction.show(mBFrag);   
    }
    else
    {
        Log.d(LOG_TAG, "Replacing AFrag -> BFrag");
        fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);
    }
    
    // Keep the transaction in the back stack so it will be reversed when backbutton is pressed
    fragmentTransaction.addToBackStack(null);

    // Commit transaction
    fragmentTransaction.commit();        
}

I call it from my container Activity; for the first time:

  • gets into the else statement and mBFrag replace mAFrag.

Then I press the back button:

  • and the operation is reversed (mAFrag is shown but.. does mBFrag is removed?).

Then I go forward again by calling showBFrag() from the same Activity:

  • and it gets AGAIN into the else statement. (so I can deduce that mBFrag is NOT ADDED)
  • but I got a Fragment already added IllegalStateException... (so why it didn't get into the if statement instead?)

So:

  1. Why is the isAdded() method not returning TRUE if I'm getting a Fragment already added IllegalStateException??
  2. Does popBackStack operation completely remove previously added fragments?
  3. What behaviour am I misunderstanding?

EDIT: Here is the complete info of the exception.

06-07 12:08:32.730: ERROR/AndroidRuntime(8576): java.lang.IllegalStateException: Fragment already added: BFrag{40b28158 id=0x7f0c0085}
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.doAddOp(BackStackRecord.java:322)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:360)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:352)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at myPackageName.containerActivity.showBFrag() // This line: "fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);"

Android Solutions


Solution 1 - Android

In the end my workaround was to execute remove() of the previous fragment and add() the new one. Although that's what replace() method was meant to do.

But I am still guessing why replace() method didn't work properly in this case. It is really weird and I want to discard that it is because I am misunderstanding something or doing something wrong.

Solution 2 - Android

If the state of the activity has already been saved its no longer safe to call commit. You must call commitAllowingStateLoss() instead. Hope this helps!

Edit: ok I've taken a closer look at your issue, problem is you are trying to add a fragment that has already been added. Even if you use replace or remove calls you can't do this. Only work around I have found is to create a new instance of a fragment and add it every time. Once you remove or replace a fragment it is best to drop all of your references to it so the GC can take care of it.

Solution 3 - Android

Probably not related to this issue directly, but I've also noticed that setting a transition to the FragmentTransaction will cause an IllegalStateException, while not setting a transition will not.

Here's the bug for this issue: http://code.google.com/p/android/issues/detail?id=25598

Solution 4 - Android

I used this:

if (getFragmentManager().findFragmentByTag(newFragment.getClass().getName()) != null) {
   transaction.remove(newFragment);
 }

and added fragment with

MyFragment frag = new MyFragment(); 
transaction.add(R.id.container, frag, MyFragment.class.getName())

MyFragment.class.getName() stands for tag

Solution 5 - Android

Check whether the frament is already added or not using the method fragment.isAdded() Do replace or add the fragment accordingly

Solution 6 - Android

try this after fragmentTransection.replace()

fragmentTransection.addToBackStack(null);
fragmentTransection.commitAllowingStateLoss();

Solution 7 - Android

Removing setOffscreenPageLimit from Viewpager solved my issue. Thanks.

Solution 8 - Android

I tried calling FragmentTransaction.remove() from onTabUnselected() and it worked around this bug.

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
	ft.add(R.id.fragment_container, fragment, null);
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
	ft.remove(fragment);
}

Solution 9 - Android

This code is working fine for me. try this

((MiActivity)getActivity()).addAccount = new AddAccount();
((MiActivity)getActivity()).addAccount.setArguments(params);
fragmentManager = getActivity().getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container((MiActivity)getActivity()).addAccount);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Solution 10 - Android

Solved it by looping through my fragments and checking if isAdded() is true, then removing that fragment. More details here.

Solution 11 - Android

use list keep fragment instance, and judge this:

        if (!mFragmentTags.contains(fragTag + "")) {
                transaction.add(R.id.tab_main_container, mCurrentFragment, fragTag + "");
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAxel M. GarciaView Question on Stackoverflow
Solution 1 - AndroidAxel M. GarciaView Answer on Stackoverflow
Solution 2 - AndroidNathan SchwermannView Answer on Stackoverflow
Solution 3 - AndroidJohan PaulView Answer on Stackoverflow
Solution 4 - AndroidNartus TeamView Answer on Stackoverflow
Solution 5 - AndroidJiju InduchoodanView Answer on Stackoverflow
Solution 6 - AndroidSaleh SheperView Answer on Stackoverflow
Solution 7 - AndroidPradeep Kumar KushwahaView Answer on Stackoverflow
Solution 8 - AndroidObviousChildView Answer on Stackoverflow
Solution 9 - AndroidMuhammad Aamir AliView Answer on Stackoverflow
Solution 10 - AndroidkylarsturnView Answer on Stackoverflow
Solution 11 - AndroidlitchiView Answer on Stackoverflow