Java 处理和缓解IllegalStateException(“故障保存状态:活动$Fragment已清除索引:-1”)
我的Android应用程序管理多个片段。但是,我在现场看到大量的崩溃,其中包含以下日志行: java.lang.IllegalStateException:故障保存状态:活动XxxFragment{81e598 id=0x7f0b0069 tag_yyy}已清除索引:-1 在堆栈溢出中搜索答案没有结果;我似乎有很多人想知道这个例外到底意味着什么。深入研究异常跟踪和Android源代码,我可以看到异常来自于我的主要活动保存其状态(FragmentActivity.onSaveInstanceState)的点,并且各个片段正在写入一个包裹中。每个片段都有一个索引(称为mIndex),该索引必须是非负的,但代码中并不清楚为什么必须是非负的,因为mIndex在该函数中不再使用 我不知道碎片是如何进入这种状态的,或者我能做些什么。我无法在自己的测试环境中重现错误。谁能解释一下如何避免和/或处理这一例外情况 相关问题: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
我将修订我之前的评论,并将其作为实际答案
setRetainInstance(true)
是一种误导。至少对我来说是这样。从这里开始:
“您很可能试图在没有引用片段的正确实例的情况下执行片段事务”
当我读到这篇文章时,我觉得这一切都是有道理的。我用碎片做了两件错事
(希望这有帮助。它太长了,不能只发表评论。)在我的例子中,我忘了检查在分离和附加它之前是否添加了
片段:
if (fragment != null && fragment.isAdded()) {
getSupportFragmentManager()
.beginTransaction()
.detach(fragment)
.attach(fragment)
.commit();
}
当你的应用程序进入后台(例如,使用Home键)时,你可能没有正确管理片段状态,当用户返回时,Android会将其杀死然后还原。您可以通过进入手机上的开发者设置,启用“不保留活动”并将“限制后台进程”设置为“无后台进程”来模拟这些条件。设置这些选项后,使用应用程序和/或使用Home键将其置于后台,打开其他应用程序,然后返回。好主意,但当我尝试此操作时,仍然无法复制行为。请参阅我的评论:正如我在此处所说,我不确定为什么删除setRetainInstance(true)
会为我解决此问题,但是如果你发现了这个错误,这是值得研究的。是的,当我完全停止持有对相关片段的引用时——只在我需要时从FragmentManager获取引用,然后让这些引用尽快超出范围——这个问题对我来说就消失了。