原因是: java.lang.IllegalStateException。片段已经添加[英] Caused by: java.lang.IllegalStateException: Fragment already added

本文是小编为大家收集整理的关于原因是: java.lang.IllegalStateException。片段已经添加的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我的MainActivity's onStart() thrws IllegalStateException带有"片段已经添加"消息.我在做什么错?

public class MainActivity extends FragmentActivity implements ServiceConnection {

    @Override
    protected void onStart() {
        super.onStart();
    }
}

以下是例外stacktrace:

java.lang.RuntimeException: 
Unable to start activity ComponentInfo{com.xxx/com.xxx.MainActivity}:
java.lang.IllegalStateException: Fragment already added: cj{38f8de4c #0 id=0x7f0b0079 cj}
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3190)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3300)
    at android.app.ActivityThread.access$1000(ActivityThread.java:211)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:6946)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
    Caused by: java.lang.IllegalStateException: Fragment already added: cj{38f8de4c #0 id=0x7f0b0079 cj}
    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1366)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:734)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682)
    at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607)
    at com.xxx.MainActivity.onStart(MainActivity.java:692)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1264)
    at android.app.Activity.performStart(Activity.java:6613)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3153)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3300) 
    at android.app.ActivityThread.access$1000(ActivityThread.java:211) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:145) 
    at android.app.ActivityThread.main(ActivityThread.java:6946) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199) 

推荐答案

您需要在替换或添加片段之前的交易中是否已经存在片段,您可以从以下代码中获得帮助:

      public void setFragmentToContainer(Fragment fragment)
        {
            final String tag = fragment.getClass().getName();
            if (manager == null) {
                manager = getSupportFragmentManager();
            }
            if (isFragmentInBackstack(manager,tag)) {
                // Fragment exists, go back to that fragment
                //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow
                manager.popBackStackImmediate(tag, 0);

            } else {
                // Fragment doesn't exist
                // STEP 1 + additional backstack management
            }

            transaction = manager.beginTransaction();
            transaction.replace(R.id.layout_content, fragment);
            if(fragment instanceof CompanyLevelFragment)
            {
                //Exit app on back press
            }else {
                transaction.addToBackStack(tag);
            }
            transaction.commit();


        }

// isFragmentInBackstack method

  public static boolean isFragmentInBackstack(final FragmentManager fragmentManager, final String fragmentTagName) {
        for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) {
            if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) {
                return true;
            }
        }
        return false;
    }

其他推荐答案

方法替换片段

public boolean replaceFragment(Fragment fragment) {
        String loadingFragment = fragment.getClass().getName();
        if (fragment.getArguments() != null && fragment.getArguments().containsKey(Constant.FRAGMENT_ID)) {
            loadingFragment += fragment.getArguments().getString(Constant.FRAGMENT_ID);
        }
        FragmentManager fragmentManager = MainActivity.getInstance().getSupportFragmentManager();
        Fragment existedFragment = fragmentManager.findFragmentByTag(loadingFragment);

        if (existedFragment != null) {
            if(getSupportFragmentManager().getBackStackEntryCount() == 1 || existedFragment.isAdded()) {
                return false;
            }
        }

        try {
            fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.content_fragment, fragment, loadingFragment);
            fragmentTransaction.addToBackStack(loadingFragment);
            //Add fix bug java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

            if(!isFinishing()) {
                fragmentTransaction.commitAllowingStateLoss();
            }
            else {
                fragmentTransaction.commit();
            }
        }
        catch (IllegalStateException ignored) {
            LogHelper.d(TAG, "IllegalStateException ignored ", ignored.getMessage());
        }
        return true;
    }

其他推荐答案

您可以快速检查:

    if(myFragment.isAdded()){
       return;
    }
// else continue with code

本文地址:https://www.itbaoku.cn/post/2091044.html

问题描述

My MainActivity's onStart() throws IllegalStateException with 'Fragment Already Added' message. What am i doing wrong?

public class MainActivity extends FragmentActivity implements ServiceConnection {

    @Override
    protected void onStart() {
        super.onStart();
    }
}

Following is exception stacktrace:

java.lang.RuntimeException: 
Unable to start activity ComponentInfo{com.xxx/com.xxx.MainActivity}:
java.lang.IllegalStateException: Fragment already added: cj{38f8de4c #0 id=0x7f0b0079 cj}
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3190)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3300)
    at android.app.ActivityThread.access$1000(ActivityThread.java:211)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:6946)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
    Caused by: java.lang.IllegalStateException: Fragment already added: cj{38f8de4c #0 id=0x7f0b0079 cj}
    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1366)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:734)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1682)
    at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607)
    at com.xxx.MainActivity.onStart(MainActivity.java:692)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1264)
    at android.app.Activity.performStart(Activity.java:6613)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3153)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3300) 
    at android.app.ActivityThread.access$1000(ActivityThread.java:211) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:145) 
    at android.app.ActivityThread.main(ActivityThread.java:6946) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199) 

推荐答案

You need check if fragment is already exists in transaction or not before replacing or adding fragment to transaction, you can take help from following code:

      public void setFragmentToContainer(Fragment fragment)
        {
            final String tag = fragment.getClass().getName();
            if (manager == null) {
                manager = getSupportFragmentManager();
            }
            if (isFragmentInBackstack(manager,tag)) {
                // Fragment exists, go back to that fragment
                //// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow
                manager.popBackStackImmediate(tag, 0);

            } else {
                // Fragment doesn't exist
                // STEP 1 + additional backstack management
            }

            transaction = manager.beginTransaction();
            transaction.replace(R.id.layout_content, fragment);
            if(fragment instanceof CompanyLevelFragment)
            {
                //Exit app on back press
            }else {
                transaction.addToBackStack(tag);
            }
            transaction.commit();


        }

// isFragmentInBackstack method

  public static boolean isFragmentInBackstack(final FragmentManager fragmentManager, final String fragmentTagName) {
        for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) {
            if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) {
                return true;
            }
        }
        return false;
    }

其他推荐答案

Method replace fragment

public boolean replaceFragment(Fragment fragment) {
        String loadingFragment = fragment.getClass().getName();
        if (fragment.getArguments() != null && fragment.getArguments().containsKey(Constant.FRAGMENT_ID)) {
            loadingFragment += fragment.getArguments().getString(Constant.FRAGMENT_ID);
        }
        FragmentManager fragmentManager = MainActivity.getInstance().getSupportFragmentManager();
        Fragment existedFragment = fragmentManager.findFragmentByTag(loadingFragment);

        if (existedFragment != null) {
            if(getSupportFragmentManager().getBackStackEntryCount() == 1 || existedFragment.isAdded()) {
                return false;
            }
        }

        try {
            fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.content_fragment, fragment, loadingFragment);
            fragmentTransaction.addToBackStack(loadingFragment);
            //Add fix bug java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

            if(!isFinishing()) {
                fragmentTransaction.commitAllowingStateLoss();
            }
            else {
                fragmentTransaction.commit();
            }
        }
        catch (IllegalStateException ignored) {
            LogHelper.d(TAG, "IllegalStateException ignored ", ignored.getMessage());
        }
        return true;
    }

其他推荐答案

You can do a quick check:

    if(myFragment.isAdded()){
       return;
    }
// else continue with code