Actions in onActivityResult and "Error Unable to complete this action after onSaveInstanceState"

An application in which a user can log in. I have the following situation: if the user is logged in, perform the else action by starting the login operation for the result, and if the result is Activity.RESULT_OK, it will execute the action.

My problem is that the action to execute is to show DialogFragment but call

DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel); newFragment.show(ft, "dialog") 

the onActivityResult callback throws an exception:

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

So how can I solve this? I think I raise the flag there and show the dialog in onResume, but I see this solution a little dirty

Edit: added more code (Im following this example to show DialogFragment

When an action is requested by the user:

 ... if (!user.isLogged()){ startActivityForResult(new Intent(cnt, Login.class), REQUEST_LOGIN_FOR_COMMENT); } 

In the same fragment

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_LOGIN_FOR_COMMENT && resultCode == Activity.RESULT_OK) { FragmentTransaction ft = getFragmentManager().beginTransaction(); DialogFragment newFragment = MyDialogFragment.newInstance(); newFragment.show(ft, "dialog") } } 

And if the user logs in activity calls,

 setResult(Activity.RESULT_OK); finish(); 
+40
java android android-fragments
Aug 24 2018-12-12T00:
source share
7 answers

The best I came up with is not to use .show (), but rather to do it.

 CheckinSuccessDialog dialog = new CheckinSuccessDialog(); //dialog.show(getSupportFragmentManager(), null); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(dialog, null); ft.commitAllowingStateLoss(); 
+92
Sep 17 '12 at 18:11
source share

Here is a workaround that works great for me.

 private void alert(final String message) { Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { public void run() { AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance(message); alertDialogFragment.show(getFragmentManager(), ALERT_DIALOG_FRAGMENT); } }); } 
+8
May 31 '13 at 14:11
source share

If using DialogFragment, the only thing that worked for me was to drop the fragment using dissmissAllowingStateLoss ()

+4
Feb 11 '14 at 12:15
source share

I just check if the action is destroyed.

 if (!getActivity().isFinishing()) { DialogFragment fragment = MyFragment.newInstance(); fragment.show(getActivity().getSupportFragmentManager(), MyFragment.TAG); } 
+3
Sep 24 '16 at 20:21
source share

Override the show(Fragment manager, String tag) function show(Fragment manager, String tag) , allowing it to lose state and change mDismissed = false; mShownByMe = true; from the origibal function by reflection:

 public class DialogParent extends DialogFragment { @Override public void show(FragmentManager manager, String tag) { try { Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed"); Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe"); mDismissed.setAccessible(true); mShownByMe.setAccessible(true); mDismissed.setBoolean(this, false); mShownByMe.setBoolean(this, true); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } FragmentTransaction ft = manager.beginTransaction(); ft.add(this, tag); ft.commitAllowingStateLoss(); } } 
+1
Dec 12 '16 at 7:59
source share

Real work.

 CheckinSuccessDialog dialog = new CheckinSuccessDialog(); //dialog.show(getSupportFragmentManager(), null); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(dialog, null); ft.commitAllowingStateLoss(); 

But still bad, because the error "Activity was destroyed" was received

 ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss(); 

So my solution adds check if (!isFinishing()&&!isDestroyed())

 CheckinSuccessDialog fragment = CheckinSuccessDialog.newInstance(); if (fragment instanceof DialogFragment) { DialogFragment dialog = (DialogFragment) fragment; if (!dialog.isAdded()) { fragmentTransaction.add(dialog, CheckinSuccessDialog.class.getName()); if (!isFinishing()&&!isDestroyed()) { fragmentTransaction.commitAllowingStateLoss(); } } 

upon dismissal:

 FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); Fragment fragment = getSupportFragmentManager().findFragmentByTag(CheckinSuccessDialog.class.getName()); if (fragment != null && fragment instanceof DialogFragment) { DialogFragment dialog = (DialogFragment) fragment; dialog.dismiss(); if (!isFinishing()&&!isDestroyed()) { fragmentTransaction.commitAllowingStateLoss(); } } 
0
May 13 '17 at 16:19
source share

This exception is thrown whenever a FragmentTrasaction committed after the FragmentManager has retained its state. An easy and clean way is to check if the FragmentManager has already saved state before showing DialogFragment .

 if(!getSupportFragmentManager.isStateSaved()) { MyDialogFragment dialogFragment = new MyDialogFragment() dialogFragment.show(getSupportFragmentManager, TAG); } 
0
Nov 29 '17 at 5:58
source share



All Articles