片段已经添加IllegalStateException

我在容器Activity上使用这个方法来显示一个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(); } 

我从我的容器Activity调用它; 首次:

  • 进入else语句,mBFragreplacemAFrag。

然后我按下后退button:

  • 和操作是相反的(mAFrag显示,但..是否删除mBFrag?)。

然后我再次通过调用showBFrag()从同一个活动:

  • 它会重新进入else语句。 (所以我可以推断mBFrag没有被添加)
  • 但我得到一个片段已经添加IllegalStateException …(所以为什么它没有进入if语句呢?)

所以:

  1. 为什么isAdded()方法不返回TRUE,如果我得到一个片段已经添加IllegalStateException ??
  2. popBackStack操作是否完全删除以前添加的片段?
  3. 我误解了什么行为?

编辑:这是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);" 

最后,我的解决方法是执行前一个片段的remove()并添加()新的片段。 虽然这就是replace()方法的意图…

但是我仍然猜测为什么replace()方法在这种情况下不能正常工作…真的很奇怪,我想放弃这是因为我误解了某些东西或者做错了什么。

如果活动状态已经保存,则不再安全地调用commit。 您必须调用commitAllowingStateLoss() 。 希望这可以帮助!

编辑:好的我仔细看看你的问题,问题是你正在试图添加一个已被添加的片段。 即使你使用replace或删除电话,你不能这样做。 只有解决方法,我发现是创build一个片段的新实例,并添加它每次。 一旦你删除或replace一个片段,最好放弃所有的引用,所以GC可以照顾它。

也许不直接涉及到这个问题,但我也注意到,设置到FragmentTransaction的转换将导致IllegalStateException,而不设置转换不会。

以下是此问题的错误: http : //code.google.com/p/android/issues/detail?id=25598

使用方法fragment.isAdded()检查是否已添加分数。相应地replace或添加分数

在fragmentTransection.replace()之后试试这个

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

我用这个:

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

并添加片段

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

MyFragment.class.getName()代表tag

我尝试从onTabUnselected()调用FragmentTransaction.remove() ,它解决了这个错误。

 @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); } 

这段代码对我来说工作正常。 尝试这个

 ((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(); 

解决它通过循环我的片段,并检查isAdded()是否为真,然后删除该片段。 更多细节在这里。

Viewpager删除setOffscreenPageLimit解决了我的问题。 谢谢。

if(mFragment.isAdded()){return; //或者返回false / true,根据你从哪里打电话来}