在调用activity.onSaveInstanceState()之后的commit()片段事务

时间:2018-05-08 07:26:13

标签: android kotlin illegalstateexception fragmenttransaction onsaveinstancestate

在我的应用程序中,我有Activity,其中包含3 Fragments。第一次创建Activity时,会显示Fragment 1。接下来,将在网络操作之后执行所有片段事务。例如:Fragment 1有一个button向服务器发出请求,当结果准备就绪时,Fragment 1使用listener来调用父activity中定义的方法{1}},用fragment 1替换fragment 2。 这种方法很好,除非父activitycallback保存其状态后收到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(){}

3 个答案:

答案 0 :(得分:0)

当您改变状态时,您是否存储了任何内容? 如果没有,那么您可以尝试commitAllowingStateLoss()

答案 1 :(得分:0)

如果在主(UI)线程上调用您的方法,

onSaveInstanceState()将无法中断您的方法。

另一种让你的生活更轻松的方法是不使用回调,而是采用像MVVM这样的反应模式。在该模式中,ActivityFragment订阅了一个可观察对象,例如网络响应和取消订阅通常在onStoponPause生命周期回调中,以便您的方法永远不会在onSaveInstanceState之后被调用。为了一个好的起点,check the official LiveData overview

答案 2 :(得分:0)

有点晚了,但是从API 26+开始,我们可以使用以下命令来检查是否需要执行常规commit或commitAllowingStateLoss()。

getSupportFragmentManager().isStateSaved();