Home » Android » android – commitAllowingStateLoss on DialogFragment

android – commitAllowingStateLoss on DialogFragment

Posted by: admin April 23, 2020 Leave a comment

Questions:

I have an IllegalStateException on showing a DialogFragment :

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

i know why its happening but i want to using commitAllowingStateLoss on showing dialog by overriding DialogFragment show function :

public void show(FragmentManager manager, String tag) {
    mDismissed = false;
    mShownByMe = true;
    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commit(); //replace it by commitAllowingStateLoss
}

but i don’t access to mDismissed and mShownByMe variables , how can i access those variables to modify them as it’s parent did.

How to&Answers:

I think to prevent throwing IllegalStateException on DialogFragment might be better to use :

 YourDialogFragment dialogFragment = new YourDialogFragment();
 fragmentManager.beginTransaction().add(dialogFragment, YourDialogFragment.TAG_FRAGMENT).commitAllowingStateLoss();

instead of using show() on DialogFragment.

Answer:

The solution about commitAllowingStateLoss works if your DialogFragment has no state to save, otherwise they will be lost like the function name told. But I think in most cases we have state to save, that is the major benefit of DialogFragment: Android recreate it and maintains its state automatically.

A better solution would be to check if the recreate process done, if not then return to caller, which is either an Activity or a FragmentActivity, it should call mark it and call the show function again later in its onPostResume() or onResumeFragments() callback, which we can make sure all fragments are recreated.

Here is an overridden show() from a subclass of DialogFragment:

public boolean show(FragmentManager fragmentManager) {
   if (fragmentManager.isStateSaved()) return false;
   show(fragmentManager, tagName);
   return true;
}

Answer:

Origin dialog fragment

public void show(FragmentManager manager, String tag) {
    mDismissed = false;
    mShownByMe = true;
    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commit(); //replace it by commitAllowingStateLoss
}

I don’t know mDismissed, mShownByMe variables used for, so should be better if override show(FragmentManager, String) method of DialogFragment and it works fine with me

override fun show(manager: FragmentManager?, tag: String?) {
    if (manager?.isDestroyed == false && !manager.isStateSaved) {
      super.show(manager, tag)
    }
  }

isStateSaved available from appcompat >= 26.0.0 or androidx