86
FATAL EXCEPTION: main
Process: com.example.loan, PID: 24169
java.lang.IllegalStateException: Fragment already added: FormFragment{428f10c8 #1 id=0x7f050055 form}
    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1192)
    at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:722)
    at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1533)
    at android.support.v4.app.FragmentManagerImpl$2.run(FragmentManager.java:489)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:450)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5068)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
    at dalvik.system.NativeStart.main(Native Method)

So, I have an android app that build with the tabhost. There are three tabs in total, in the tab2, there is a button to make the fragment transaction in tab2 (which is calling the function in the fragment activity)

FragmentTransaction t = getSupportFragmentManager().beginTransaction();
        t.replace(R.id.realtabcontent, mFrag);
        t.addToBackStack(null);
        t.commit();

There is exception if I run like this:

  1. Inside the tab2, I press the button to change fragment
  2. Go to other tab (eg. tab 1 or tab 3)
  3. Press back button
  4. Throw exception

How to fix that? Thanks for helping

JJD
  • 44,755
  • 49
  • 183
  • 309
user782104
  • 12,011
  • 51
  • 154
  • 289
  • possible duplicate of [IllegalStateException: Fragment already added appears if a App was very long in the background](http://stackoverflow.com/questions/24629080/illegalstateexception-fragment-already-added-appears-if-a-app-was-very-long-in) – fweigl Sep 19 '14 at 04:36
  • that means the backpress is adding a new fragment , what is the logic in the backstack ? Thanks a lot – user782104 Sep 19 '14 at 04:37
  • is mFrag is added to some other tab also apart from tab2 ? – Akhil Sep 19 '14 at 06:29

13 Answers13

157

This happens when we try to add same fragment or DialogFragment twice before dismissing,

just call

if(mFragment.isAdded())
{
     return; //or return false/true, based on where you are calling from
}

Having said that, I don't see any reason why to remove old fragment and add the same fragment again since we can update the UI/data by simply passing parameters to the method inside the fragment

Ujju
  • 2,345
  • 3
  • 19
  • 33
  • 6
    This should be the accepted answer. The accepted answer makes no sense. First, there should be no negation of `isAdded()`. Second, in the comments, it is suggested that this code goes in `onCreate()`, which is also nonsensical. This line of code should be placed directly before the line where the fragment is added (or replaced), not in `onCreate()` or `onCreateView()`. It's too late to execute that code in either of those methods. – AndroidDev Oct 01 '15 at 16:28
  • 4
    `if(fragment.isAdded()) fragmentTransaction.show(fragment);` – Konstantin Konopko Feb 16 '18 at 13:02
  • also must be checked for hiding fragments. – Mahdi Moqadasi Mar 31 '19 at 10:10
  • I need to add similar fragments and only attributes in the fragment are different. But duplicated error still occurs. – Alston Sep 07 '19 at 10:29
  • i had already implemented to check if fragment already added then return (the code of add fragment will not be executed) , as the my application is live on the play store still i got the crash fragment is already added from the some of the devices not all the devices i am trying to figure it out from the month ago, i can not over come it, i had applied numbers of solutions and update the build on the live play store, still i am receiving the error from the some of the devices like Galaxy S20+ 5G, huawei , there fewer devices that have the issue i got, any help would be appreciated thanks – Navin Jul 09 '20 at 06:19
13

Remove the old fragment in case it is still added and then add the new fragment:

FragmentManager fm = getSupportFragmentManager();
Fragment oldFragment = fm.findFragmentByTag("fragment_tag");
if (oldFragment != null) {
    fm.beginTransaction().remove(oldFragment).commit();
}
MyFragment newFragment = new MyFragment();
fm.beginTransaction().add(newFragment , "fragment_tag");
vovahost
  • 25,072
  • 12
  • 95
  • 99
  • shouldn't we send arguments to make any changes to the already displayed fragment? instead of removing and adding it again – Ujju May 28 '18 at 07:32
  • You cannot set the arguments after the fragment was added to the fragment manager. From docs: "This method cannot be called if the fragment is added to a FragmentManager and if isStateSaved() would return true." So you need to call your fragment methods directly if you want to update UI. – vovahost May 28 '18 at 11:40
  • yes, I didn't mean setting via `setArguments`, was referring to sending arguments as params to update, so removing and adding the same fragment has no use right ? – Ujju May 28 '18 at 11:49
  • It depends. If you need to reconfigure a lot of things it may be easier to just replace the fragment with a new one. It all depends of your needs. – vovahost May 28 '18 at 13:08
  • Is it better to have 2 transactions instead of 1? – CoolMind Mar 15 '19 at 15:47
  • Not really, using a single transaction should work as well. – vovahost Mar 16 '19 at 05:18
  • 1
    I continue receiving the error, if use one transaction. Probably this is due to asynchronous behaviour of work with fragment manager. – CoolMind Jul 01 '19 at 09:28
8

You just have to check one condition in your fragment mentioned below:

if(!isAdded())
{
    return;
}

isAdded = Return true if the fragment is currently added to its activity. Taken from the official document. This will not add that fragment if it is already added

Check below link for a reference:
http://developer.android.com/reference/android/app/Fragment.html#isAdded()

Deep Mehta
  • 1,201
  • 2
  • 11
  • 16
7

Sometimes it happens for not finding proper id from the respective layout. I faced this problem. Then after many hours I found that I set wrong recyclerview id. I change it, and works fine for me.

So, double check your fragment layout.

Mihab
  • 91
  • 1
  • 6
7

You just have to check one condition before start fragment transaction

 if (!fragmentOne.isAdded()){
            transaction = manager.beginTransaction();
            transaction.add(R.id.group,fragmentOne,"Fragment_One");
            transaction.commit();
 }

this is working perfactly for me...

Mehul Solanki
  • 948
  • 8
  • 15
1

I have this error when not wrapping my body XML inside a ViewGroup inside FrameLayout.

Error:

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".screens.home.HomeEpoxyFragment">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            android:overScrollMode="never"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</FrameLayout>

Solved:

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".screens.home.HomeEpoxyFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv"
                android:overScrollMode="never"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>

Hope this may help someone.

0

For me it works like:

Fragment oldFragment = manager.findFragmentByTag(READER_VIEW_POPUP);
if (oldFragment != null) {
    manager.beginTransaction().remove(oldFragment).commit();
}

FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
Farid Haq
  • 1,919
  • 15
  • 13
0

It even can occur if in FragmentStatePagerAdapter of your ViewPager you create an item that already exists:

override fun getItem(position: Int): Fragment {
    return tabs[0] // Right variant: tabs[position]
}

(private val tabs: List<Fragment> is a list of fragments in tabs).

CoolMind
  • 16,738
  • 10
  • 131
  • 165
  • How did you solve this? It's very similar to my use-case – Mitch Oct 24 '19 at 09:51
  • @Mitch, I wrote `return tabs[position]` in the second line. – CoolMind Oct 24 '19 at 11:48
  • I'm also using the same concept as `return tabs[position]` but it still throws an error – Mitch Oct 24 '19 at 20:58
  • @Mitch, sorry, I don't know without a code. For general case currently I use https://stackoverflow.com/a/57161814/2914140. Do you think `FragmentStatePagerAdapter` throws the error in `getItem`? – CoolMind Oct 24 '19 at 21:02
  • It's very likely to be the source of the error since it's where the instance(s) of the fragment(s) shown by the `ViewPager` are retrieved – Mitch Oct 24 '19 at 21:12
  • just posted a question https://stackoverflow.com/questions/58549379/fragmentpageradapter-throwing-illegalargumentexception-fragment-already-added with my sample code. Kindly take a look at it to gain a better understanding of my situation – Mitch Oct 24 '19 at 21:33
0

To my surprise, I made stupid mistake by calling the fragment transaction twice:

if (!FirebaseManager.isClientA && !FirebaseManager.isClientB) {
      fragment = new FragmentA();
      getFragmentManager().beginTransaction().add(R.id.fragment_frame, fragment, null).addToBackStack("").commit();
} else if (FirebaseManager.isClientB) {
      fragment = new FragmentB();
} else {
      fragment = new FragmentC();
}
getFragmentManager().beginTransaction().add(R.id.fragment_frame, fragment, null).addToBackStack("").commit();

Make sure you don't make the same mistake.

Seto
  • 869
  • 11
  • 29
0

Add Fragment as below

FragmentTransaction t = getSupportFragmentManager().beginTransaction();
    t.replace(R.id.realtabcontent, mFrag);
    t.addToBackStack(null);
    t.commitNowAllowingStateLoss();
M.Noman
  • 1,537
  • 15
  • 12
  • What will happen with old and new fragments? Will it replace old with new? – CoolMind Jul 01 '19 at 09:30
  • No, it will not replace it will add the previous fragment to back stack. – M.Noman Jul 02 '19 at 10:19
  • I wonder, is it possible? Yesterday I tried similar code and got an error, see https://stackoverflow.com/questions/38566628/how-is-the-new-fragmenttransaction-commitnow-working-internally/, because `addToBackStack` is not allowed together with `commitNow`. – CoolMind Jul 02 '19 at 11:18
  • In that link, he is manually disabling the back stack. With addToBackStack it will enable to manage back stack of fragment – M.Noman Jul 02 '19 at 11:41
0

You can try this:

 if (dialogFolderGallery.isAdded()) {
                dialogFolderGallery.dismiss();
            } else { //bla...bla..
}
Dino
  • 6,207
  • 8
  • 28
  • 62
Mr. Lemon
  • 199
  • 2
  • 5
0

I got this error when incorrectly used my ViewModel inside of Fragment like this:

//This is wrong!
MyViewModel viewModel = new MyViewModel(getActivity().getApplication());

Correct way:

viewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
Kamil Radz
  • 23
  • 7
0

Here my solution for Dialog Fragment (you can use this concept also for fragment class)

I have try to click show dialog fragment by tap button multiple time and quickly.

            FragmentManager fm = getSupportFragmentManager();
            Fragment oldFragment = fm.findFragmentByTag("wait_modal");

            if(oldFragment != null && oldFragment.isAdded())
                return;

            if(oldFragment == null && !please_wait_modal.isAdded() && !please_wait_modal.isVisible()){
                fm.executePendingTransactions();
                please_wait_modal.show(fm,"wait_modal");
            }
Yohanes AI
  • 2,632
  • 6
  • 42
  • 75