I have a Handler which displays a DialogFragment when it receives a particular message. This usually works, but if the fragment has already been saved, I get the following error:
E/AndroidRuntime( 3898): FATAL EXCEPTION: main E/AndroidRuntime( 3898): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState E/AndroidRuntime( 3898): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) E/AndroidRuntime( 3898): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) E/AndroidRuntime( 3898): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) E/AndroidRuntime( 3898): at android.support.v4.app.DialogFragment.show(DialogFragment.java:123) E/AndroidRuntime( 3898): at com.malauzai.app.BaseActivity$2.handleMessage(BaseActivity.java:72) E/AndroidRuntime( 3898): at android.os.Handler.dispatchMessage(Handler.java:99)
Now, I know that this is expected, based on the Javadoc for FragmentManager.beginTransaction:
Note: A fragment transaction can only be created/committed prior to an activity saving its state. If you try to commit a transaction after Activity.onSaveInstanceState() (and prior to a following Activity.onStart or Activity.onResume(), you will get an error. This is because the framework takes care of saving your current fragments in the state, and if changes are made after the state is saved then they will be lost.
My problem is that I can't tell how to prevent it. I've tried calling Handler.removeMessages()
on onPause()
, but it still occurs. I've tried setting a flag in onSaveInstanceState()
and not showing the fragment if it's set, but it still occurs. This seems like a pretty common problem, but I can't come up with a solution that works. Basically, how do I know that the fragment has already been saved?
BTW, this occurs on my BaseActivity (extends FragmentActivity), but each activity has its own handler, so I don't think this should be an issue.
My last thought is using Fragment.commitAllowingStateLoss()
, but that seems like a hack.
EDIT: Here's the code that's causing me problems:
private final Handler mTimerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TIMER_MESSAGE_LOGOUT_WARNING:
// throws IllegalStateException if fragment is already saved
new LogoutWarningDialog().show(getSupportFragmentManager(),
"dialog");
break;
}
}
};
I assume in my answer that you are using FragmentManager and add Fragments through FragmentTransacts with tags (or ids).
so basically inside your BaseActivity
you could just do something like this
FragmentManager manager = getFragmentSupportedManager();
Fragment fragmentIWannaKnowIfexists = manager.findFragmentByTag("Tag I used to create this Fragment inside FragmentTrasnsaction")
// or manager.findFragmentById(ID_FROM_LAYOUT)
if(fragmentIWannaKnowIfexists != null){
//we have this Fragment already
} else {
// this Fragment was not added already
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With