在我的应用程序中,我有Activity
,其中包含3 Fragments
。第一次创建Activity
时,会显示Fragment 1
。接下来,将在网络操作之后执行所有片段事务。例如:Fragment 1
有一个button
向服务器发出请求,当结果准备就绪时,Fragment 1
使用listener
来调用父activity
中定义的方法{1}},用fragment 1
替换fragment 2
。
这种方法很好,除非父activity
在callback
保存其状态后收到onSaveInstanceState()
。抛出IllegalStateException
。
我已经阅读了有关此问题的一些答案,例如this post,我理解为什么会因this blog而发生此异常。
我还举了一个例子,我发现here试图解决问题。这篇文章建议在致电activity
之前始终检查commit()
是否正在运行。所以我在父Boolean
中声明了activity
变量,并将其值false
中的onPause()
和true
中的onResume()
。{ / p>
网络操作完成后调用的父活动回调就像这段Kotlin
代码,其中next
是替换fragment
的编号:
private fun changeFragment(next:Int){
// get the instance of the next fragment
val currentFragment = createFragment(next)
// do other stuff here
if(isRunning){
// prepare a replace fragment transaction and then commit
ft.commit()
}else{
// store this transaction to be executed when the activity state become running
}
}
此代码工作正常,现在我不再获得Exception
了,但我的问题是:在我检查{{1}之后调用onSaveInstanceState()
是可能的在我调用if(isRunning)
之前,以便在保存活动状态之后发生commit()会再次导致ft.commit()
?
我不确定IllegalStateException
是否可以在任何时间点中断我的onSaveInstanceState()
方法。有可能吗?
如果存在这种可能性,我的代码可能会在changeFragment()
和if(isRunning)
之间中断,我能做些什么?
可以解决这样添加ft.commit()
块的问题吗?:
try{}catch(){}
答案 0 :(得分:0)
当您改变状态时,您是否存储了任何内容?
如果没有,那么您可以尝试commitAllowingStateLoss()
。
答案 1 :(得分:0)
onSaveInstanceState()
将无法中断您的方法。
另一种让你的生活更轻松的方法是不使用回调,而是采用像MVVM这样的反应模式。在该模式中,Activity
或Fragment
订阅了一个可观察对象,例如网络响应和取消订阅通常在onStop
或onPause
生命周期回调中,以便您的方法永远不会在onSaveInstanceState
之后被调用。为了一个好的起点,check the official LiveData overview。
答案 2 :(得分:0)
有点晚了,但是从API 26+开始,我们可以使用以下命令来检查是否需要执行常规commit或commitAllowingStateLoss()。
getSupportFragmentManager().isStateSaved();