In my application I have an Activity
that holds 3 Fragments
. The very first time the Activity
is created, Fragment 1
is displayed. Next, all fragment transactions will be executed after a network operation. For example: Fragment 1
has a button
to make a request to the server and when the result is ready, Fragment 1
uses a listener
to call a method defined inside the parent activity
, to replace fragment 1
with fragment 2
.
This works fine, except when the parent activity
receives the callback
after its state has been saved by onSaveInstanceState()
. An IllegalStateException
is thrown.
I've read some answers about this problem, for example this post and I understood why this exception happens thanks to this blog.
I also take an example that I found here to try to solve the problem. This post suggests to always check if the activity
is running before call commit()
. So I declared a Boolean
variable in the parent activity
and I put its value to false
in onPause()
and to true
in onResume()
.
The parent activity callback called after network operations has been completed is something like this piece of Kotlin
code, where next
is the number of the replacing 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
}
}
This code is working fine and now I'm not getting the Exception
anymore, but my question is: it's possible that onSaveInstanceState()
is called after I check if(isRunning)
and before I call ft.commit()
, so that the commit() happens after the activity state has been saved causing IllegalStateException
again?
I'm not sure if onSaveInstanceState()
could interrupt my changeFragment()
method at any point in time. Is it possible?
If the possibility exists and my code may be interrupted between if(isRunning)
and ft.commit()
, what I can do?
It could be solved adding a try{}catch(){}
block like this?:
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
}