Search code examples
androidandroid-fragmentsandroid-fragmentactivityandroid-dialogfragmentillegalstateexception

IllegalStateException while showing DialogFragment after back from AppCompatActivity


I am starting a FragmentActivity from a custom DialogFragment and after I come back the original Activity and try to open the dialog again I get:

IllegalStateException: Can not perform this action after onSaveInstanceState

I don't understand why is it happening, if I dismiss the dialog from the original activity than I can show it again as many times as I want, but if I start a new Activity from the DialogFragment after that I cannot show any dialog again because I get the exception.

Here is my code, this method is in my DialogFragment:

 public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3){
     mSearchLocationType = position;
     switch(position){
         case PSL_CURRENT_POSITION: // I can show the dialog again after this.
             break;
         case PSL_MAP_POINT:
             Intent selectMapPoint = new Intent(parentActivity, SelectMapPointActivity.class);     
             selectMapPoint.putExtra(SelectMapPointFragment.EXTRA_SELECTED_POS, mSearchLocation);
             parentActivity.startActivityForResult(selectMapPoint, REQ_MAP_POINT); 
             // After returning this Activity and trying to show ANY DialogFragment the app crashes.
             break;
         case PSL_ADDRESS:
             Intent selectAddress = new Intent(parentActivity, SelectAddressActivity.class);
             parentActivity.startActivity(selectAddress); // Also from this Activity, makes no difference.
             break;
      }
      dismiss();
 }    

I am showing the dialog like:

if(!selectPoiAroundDialog.isVisible())
    selectPoiAroundDialog.show(parentActivity.getSupportFragmentManager(), "mSelectPoiCategoryDialog");

What I have tried already:

  • Override the show() method of the DialogFragment and use this code to show the dialog:

    FragmentTransaction ft = manager.beginTransaction();
    ft.add(this, tag);
    ft.commitAllowingStateLoss();

  • Debug the app and check if all the lifecycle methods are called, but it seems normal to me, each of the times the onDestroyView() method of the DialogFragment is called.

  • Override the show() and onDismiss() method of the DialogFragment and track if it is shown or not.

This is a corporate app and has a bad design, so the class which I am trying to modify (where I am showing the dialog) is not child of Activity or Fragment. ´parentActivity´ is accessed by a static method of the application class, but I am sure that it has the right Activity. Do you think this can cause the problem?

EDIT: The full stacktrace is when I useing commitAllowStateLoss():

 java.lang.IllegalStateException: Activity has been destroyed
 at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1515)
 at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638)
 at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:621)
 at com.mycompany.dialog.GTDialog.show(GTDialog.java:174)
 at com.mycompany.fragment.content.SearchOfflinePOIContent$2.onClick(SearchOfflinePOIContent.java:250)
 at android.view.View.performClick(View.java:5201)
 at android.view.View$PerformClick.run(View.java:21209)
 at android.os.Handler.handleCallback(Handler.java:739)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:148)
 at android.app.ActivityThread.main(ActivityThread.java:5525)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
  • I also tried to override the onSaveInstanceState() method, it didn't helped.

EDIT2: The original stacktrace is:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:617)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:139)
at com.mycompany.dialog.GTDialog.show(GTDialog.java:174)
at com.mycompany.fragment.content.SearchOfflinePOIContent$1.onClick(SearchOfflinePOIContent.java:197)
at android.view.View.performClick(View.java:5201)
at android.view.View$PerformClick.run(View.java:21209)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

If I override the show() method and try to commit the fragment with commitAllowingStateLoss() than I get the first exception.


Solution

  • I figured out the problem. When the app quit from an Activity it didn't remove the reference of it from parentActivity, so when I tried to show the dialog again I gave a reference of the destroyed activity.

    Thanks for your time!