Java 处理和缓解IllegalStateException(“故障保存状态:活动$Fragment已清除索引:-1”)

Java 处理和缓解IllegalStateException(“故障保存状态:活动$Fragment已清除索引:-1”),java,android,android-fragments,Java,Android,Android Fragments,我的Android应用程序管理多个片段。但是,我在现场看到大量的崩溃,其中包含以下日志行: java.lang.IllegalStateException:故障保存状态:活动XxxFragment{81e598 id=0x7f0b0069 tag_yyy}已清除索引:-1 在堆栈溢出中搜索答案没有结果;我似乎有很多人想知道这个例外到底意味着什么。深入研究异常跟踪和Android源代码,我可以看到异常来自于我的主要活动保存其状态(FragmentActivity.onSaveInstanceSta

我的Android应用程序管理多个片段。但是,我在现场看到大量的崩溃,其中包含以下日志行:

java.lang.IllegalStateException:故障保存状态:活动XxxFragment{81e598 id=0x7f0b0069 tag_yyy}已清除索引:-1

在堆栈溢出中搜索答案没有结果;我似乎有很多人想知道这个例外到底意味着什么。深入研究异常跟踪和Android源代码,我可以看到异常来自于我的主要活动保存其状态(FragmentActivity.onSaveInstanceState)的点,并且各个片段正在写入一个包裹中。每个片段都有一个索引(称为mIndex),该索引必须是非负的,但代码中并不清楚为什么必须是非负的,因为mIndex在该函数中不再使用

我不知道碎片是如何进入这种状态的,或者我能做些什么。我无法在自己的测试环境中重现错误。谁能解释一下如何避免和/或处理这一例外情况

相关问题:


我将修订我之前的评论,并将其作为实际答案
setRetainInstance(true)
是一种误导。至少对我来说是这样。从这里开始:

“您很可能试图在没有引用片段的正确实例的情况下执行片段事务”

当我读到这篇文章时,我觉得这一切都是有道理的。我用碎片做了两件错事

  • 我讨厌的片段是单身汉。(主要编号)
  • 我试图在没有正确保存状态的情况下跨活动使用这些相同的片段实例。(可以通过这里提到的方法实现:)

  • (希望这有帮助。它太长了,不能只发表评论。)

    在我的例子中,我忘了检查在分离和附加它之前是否添加了
    片段:

    if (fragment != null && fragment.isAdded()) {
                getSupportFragmentManager()
                        .beginTransaction()
                        .detach(fragment)
                        .attach(fragment)
                        .commit();
            }
    

    当你的应用程序进入后台(例如,使用Home键)时,你可能没有正确管理片段状态,当用户返回时,Android会将其杀死然后还原。您可以通过进入手机上的开发者设置,启用“不保留活动”并将“限制后台进程”设置为“无后台进程”来模拟这些条件。设置这些选项后,使用应用程序和/或使用Home键将其置于后台,打开其他应用程序,然后返回。好主意,但当我尝试此操作时,仍然无法复制行为。请参阅我的评论:正如我在此处所说,我不确定为什么删除
    setRetainInstance(true)
    会为我解决此问题,但是如果你发现了这个错误,这是值得研究的。是的,当我完全停止持有对相关片段的引用时——只在我需要时从FragmentManager获取引用,然后让这些引用尽快超出范围——这个问题对我来说就消失了。