【问题标题】:Popping backstack throws "Fragment Already Added" exception弹出回栈会引发“已添加片段”异常
【发布时间】:2019-09-19 10:49:03
【问题描述】:

我一直在尝试解决有关后台管理的最奇怪的问题。

目标是有如下逻辑(片段用字母A、B、C表示):

A -> B, B -> C ,当回压时,C -> A

由于C可以是不同的片段,并且在C和backPressed中时,片段B永远不会出现,我将转换A->B添加到backstack并且没有添加B->C,只是将B替换为C,所以当我做backPress,C去A。

这在第一次时完美运行 - 行为符合预期,但是当我连续第二次尝试时,应用程序崩溃:

getSupportFragmentManager().popBackStackImmediate()

,抛出异常:

java.lang.IllegalStateException: Fragment already added: FragmentC
...

我尝试用getSupportFragmentManager().popBackStack 替换,但只是在几纳秒后抛出错误。

在尝试从堆栈中弹出片段时,是否有任何原因会引发添加错误?关于如何解决这个问题的任何想法?

提前非常感谢

【问题讨论】:

  • 您添加或更新片段了吗?如果你每次都添加那么就会发生
  • 显示一些代码。

标签: android android-fragments back-stack


【解决方案1】:

它不是由于返回堆栈弹出而引发异常,而是由于 (A) 已附加而引发异常。确保在去 B 和 C 时使用 remove 或 replace,以防止 A 处于添加/附加状态。

【讨论】:

    【解决方案2】:

    如果没有看到您的代码,很难确切地说出问题所在,但我有一个合理的想法。片段回栈只存储 FragmentTransactions,而不是实际的片段。当您单击返回时它会弹出,它只是简单地反转该事务,因为它得到它。因此,在您的情况下,您首先进行替换事务或任何 [Remove A -> Add B] 并添加到后台堆栈。然后你去 B->C 并且不要将它添加到后台堆栈。所以backstack现在仍然是[Add A -> Remove B]。请记住,backstack 只是反向的正向交易。现在你在后台堆栈不知道的 C 上,然后单击返回,Android 执行后台堆栈。它添加了 A 并尝试删除 B,但 B 不存在所以什么也没有发生。所以现在你回到了 A 片段,下面是你可能不知道的 C 片段。您可以在调试器中确认此 C 片段落后。

    现在您说第二次单击返回时它会崩溃。所以你回到了 A,下面有 C 片段,你从 A->B 开始并添加到后台堆栈。您可能正在使用 replace 删除所有添加的片段并添加新片段。所以事务是[删除A,删除下面的C,添加B]并将其添加到后台堆栈。现在您从 B->C 开始,如果没有看到您的代码,我无法确定这一点。您收到Fragment already added 错误,这意味着您必须在从 B->C 的某个地方获取相同的 C 实例。您是否在替换中使用了一些findFragmentByTag

    因此,您从第一次加载并可见相同的 C 片段实例,然后单击返回。 Android 会尝试反转之前的事务并尝试添加 A 有效,然后添加 C,它与当前可见的片段实例相同,您会收到 Fragment already added 错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-07
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 2021-08-17
      • 1970-01-01
      相关资源
      最近更新 更多