В моем приложении у меня есть Activity
, который содержит 3 Fragments
. При первом создании Activity
отображается Fragment 1
. Далее все транзакции фрагментов будут выполнены после сетевой операции. Например: Fragment 1
имеет button
для запроса к серверу, а когда результат готов, Fragment 1
использует listener
для вызова метода, определенного внутри родительского activity
, для замены fragment 1
с fragment 2
.
Это прекрасно работает, за исключением случаев, когда родительский элемент activity
получает callback
после того, как его состояние было сохранено onSaveInstanceState()
. IllegalStateException
брошен.
Я прочитал несколько ответов об этой проблеме, например в этом посте , и я понял, почему это исключение происходит благодаря этому блогу .
Я также беру пример, который нашел здесь , чтобы попытаться решить проблему. Этот пост предлагает всегда проверять, работает ли activity
перед вызовом commit()
. Поэтому я объявил переменную Boolean
в родительском activity
и установил ее значение в false
в onPause()
и true
в onResume()
.
Обратный вызов родительской активности, вызываемый после завершения сетевых операций, выглядит примерно так: 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
, но мой вопрос: возможно, что onSaveInstanceState()
вызывается после того, как я проверяю if(isRunning)
и до того, как я вызываю ft.commit()
, так что commit () происходит после того, как состояние активности было сохранено, вызывая IllegalStateException
снова?
Я не уверен, что onSaveInstanceState()
может прервать мой метод changeFragment()
в любой момент времени. Возможно ли это?
Если такая возможность существует и мой код может быть прерван между if(isRunning)
и ft.commit()
, что я могу сделать?
Это может быть решено добавлением блока try{}catch(){}
следующим образом:
if(isRunning){
try{
ft.commit()
}catch(ie:IllegalStateException){
// store the transaction and execute it when the activity become running
}
}else{
// store the transaction and execute it when the activity become running
}