片段已添加IllegalStateException

Axe*_*cia 55 android fragment illegalstateexception android-fragments android-3.0-honeycomb

我在容器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();        
}
Run Code Online (Sandbox Code Playgroud)

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

  • 进入else语句,mBFrag替换为mAFrag.

然后我按下后退按钮:

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

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

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

所以:

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

编辑:这是异常的完整信息.

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);"
Run Code Online (Sandbox Code Playgroud)

Axe*_*cia 42

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

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

  • @ AMGG,@ sswiz,这也是CPL中的一个错误.问题出现在`BackStackRecord:popFromBackStack`中,在'OP_REPLACE'上,活动被分配给已被删除的片段中的变量,而不是被重新添加的片段中的变量.我会提出一个错误报告,除非其他人有这样的愿望.是否有人需要澄清他们的答案,因为它是一个bug的解决方法,并且没有必要挂在引用上的问题?干杯伙计们. (10认同)
  • @AMGG,@ sswiz [错误报告链接](http://code.google.com/p/android/issues/detail?id=17488).问题17488. (6认同)
  • 有没有人找到更好的解决方案来解决这个问题,或者正在使用remove()然后添加()现在唯一可行的解​​决方案? (2认同)
  • 你说删除了以前的片段,但你怎么找到这个片段?使用FragmentManager? (2认同)

Nat*_*ann 12

如果活动的状态已经保存,则不再可以安全地调用提交.你必须打电话commitAllowingStateLoss().希望这可以帮助!

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


Joh*_*aul 8

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

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