片段已添加IllegalStateException

时间:2011-06-06 10:16:52

标签: android android-3.0-honeycomb android-fragments fragment 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语句,mBFrag替换为mAFrag。

然后我按下后退按钮:

  • 并且操作被反转(显示了mAFrag,但是..删除了mBFrag?)。

然后我通过从同一个Activity调用showBFrag()再次前进:

  • 并且它获得了进入else语句的AGAIN。 (所以我可以推断mBFrag没有添加)
  • 但我得到了一个片段已经添加了IllegalStateException ...(那么为什么它没有进入if语句?)

所以:

  1. 如果我的片段已经添加了IllegalStateException ,为什么isAdded()方法不返回TRUE?
  2. popBackStack操作是否完全删除以前添加的片段?
  3. 我误解了什么行为?
  4. 编辑: 以下是异常的完整信息。

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

11 个答案:

答案 0 :(得分:41)

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

但我仍然猜测为什么在这种情况下,replace()方法没有正常工作......真的很奇怪,我想抛弃它是因为我误解了某些事情或做错了什么。

答案 1 :(得分:12)

如果活动的状态已经保存,则不再可以安全地调用提交。您必须改为呼叫commitAllowingStateLoss()。希望这有帮助!

编辑:好的我已仔细研究过您的问题,问题是您是否正在尝试添加已添加的片段。即使您使用替换或删除呼叫,也无法执行此操作。我找到的唯一解决方法是创建片段的新实例并每次添加它。删除或替换片段后,最好删除所有对它的引用,以便GC可以处理它。

答案 2 :(得分:8)

可能与此问题没有直接关系,但我也注意到设置到FragmentTransaction的转换会导致IllegalStateException,而不会设置转换。

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

答案 3 :(得分:1)

使用方法fragment.isAdded()检查是否已添加片段。相应地替换或添加片段

答案 4 :(得分:1)

我用过这个:

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

这段代码对我来说很好。试试这个

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

答案 7 :(得分:0)

通过循环遍历我的片段并检查isAdded()是否为真来解决它,然后删除该片段。 More details here.

答案 8 :(得分:0)

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

答案 9 :(得分:0)

如果

(mFragment.isAdded()) {      返回; //或根据您的来电地点返回false / true }

答案 10 :(得分:0)

使用列表保持片段实例,并判断:

        if (!mFragmentTags.contains(fragTag + "")) {
                transaction.add(R.id.tab_main_container, mCurrentFragment, fragTag + "");
}