简体   繁体   中英

PagerAdapter.getItem() crash with IllegalStateException: Fragment already added

I have this code for FragmentStatePagerAdapter.getItem():

(logd() is just a static method that calls Log.d()).

@Override
public Fragment getItem(int position) {

    logd("Fragment for position: " + position);

    Fragment currFragment = null;
    List<Fragment> allFragments = mFragmentManager.getFragments();
    if (allFragments.size() == 0) {

        logd("No Fragments cached.");
    } else {

        currFragment = allFragments.get(position);
        logd("Found a cached Fragment: " + currFragment);
    }

    if (currFragment == null) {

        currFragment = MyCustomFragment.create(position);
    }

    logd("Returning Fragment: Position: " + position + " Fragment: " + currFragment.toString());
    return currFragment;
}

But it keeps crashing with:

    --------- beginning of crash
2020-07-27 10:45:44.492 6271-6271/com.example.package E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.package, PID: 6271
    java.lang.IllegalStateException: Fragment already added: MyCustomFragment{7c7e778} (5f284a0f-a00f-4be2-8098-a3e8dc65c9cb) id=0x7f09024e}
        at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
        at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6592)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)

This has me totally stumped. Can someone help why this crash is happening?

As far as I can make out, the same code construct works elsewhere in my app.

I did see several other SO questions with the same exception, but none that dealt specifically with Fragments inside ViewPager+TabLayout combinations.

Edit: Even this code crashes with the same exception:

@Override
public Fragment getItem(int position) {

    Fragment currFragment = MyCustomFragment.create(position);
    logd("Returning Fragment: Position: " + position + " Fragment: " + currFragment.toString());
    return currFragment;
}

Edit: Adding the code of MyCustomFragment.create():

public static MyCustomFragment create(int position) {

    Bundle args = new Bundle();
    args.putInt("position", position);
    MyCustomFragment f = new MyCustomFragment();
    f.setArguments(args);
    logd("Creating Fragment at position: " + position);
    return f;
}

Edit:

It seems that if I return new Fragment() from getItem(), everything works. If I return new MyCustomFragment() from getItem(), I get the crash. MyCustomFragment does not even have any constructor; it relies on the default one (though I did try with a no-arg constructor that just calls super(); still the crash persists).

You cannot use an already added Fragment in another place. When this line of code is executing:

currFragment = allFragments.get(position);

according to the log , it means the fragment in you list is already added somewhere (in a different place or very same place). In other words, in getItem(int position) , you can only add a new instance of a Fragment . So remove this code block:

else {

    currFragment = allFragments.get(position);
    logd("Found a cached Fragment: " + currFragment);
}

And this exception should go away.

The problem was that within MyCustomFragment, in the onCreateView() method, the IDE-stub code of return super.onCreateView() was left in place inadvertently. The superclass, Fragment, returns null from its onCreateView() under certain conditions. It appears that this null return from onCreateView() was creating the problem. I inflated a test layout in MyCustomFragment's onCreateView() and now the crash is gone.

The exception looks incorrectly worded if that is indeed the case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM