我的主要活动onStart()
抛出IllegalStateException
已经添加了片段'信息。我做错了什么?
public class MainActivity extends FragmentActivity implements ServiceConnection {
@Override
protected void onStart() {
super.onStart();
}
}
以下是异常堆栈跟踪:
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)
答案 0 :(得分:2)
在替换或添加片段到事务之前,您需要检查事务中是否已经存在片段,您可以从以下代码中获取帮助:
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;
}
答案 1 :(得分:2)
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;
}
答案 2 :(得分:1)
我使用了Reena解决方案,但我修改了它用于backstacks,因为有时你不希望当前片段到后栈。 Reena给出了一个很好的解决方案,应该有更多的选票。
public void setFragmentToContainer(Fragment fragment,boolean adddToBackStack)
{
final String tag = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
if (isFragmentInBackstack(manager,tag)) {
// Fragment exists, go back to that fragment
manager.popBackStackImmediate(tag, 0);
} else {
// Fragment doesn't exist
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fl_cart_detail_host_layout, fragment);
if(adddToBackStack) transaction.addToBackStack(tag);
transaction.commit();
}
}
答案 3 :(得分:0)
您可以进行快速检查:
if(myFragment.isAdded()){
return;
}
// else continue with code