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

后端 未结 10 1129
孤独总比滥情好
孤独总比滥情好 2020-12-09 01:56

I am facing issue with DialogFragment / getSupportFragmentManager / Android version 4.x

01-10 19:46:48.228: E/AndroidRuntime(9879): java.lang.IllegalStateExc         


        
相关标签:
10条回答
  • 2020-12-09 02:10

    In the Activity, before showing the dialog you can do something like this

    getSupportFragmentManager().executePendingTransactions();
    

    This worked for me.

    0 讨论(0)
  • 2020-12-09 02:14

    It works:

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

    But but still bad, because got error “Activity has been destroyed”

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

    So my solution is add 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();
                        }
                    }
    

    on dismiss:

      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 讨论(0)
  • 2020-12-09 02:20

    I got the same issue and I changed the code as bellow

    newFragment.show(transactionFragment, "dialog");
    

    to:

    transactionFragment.add(android.R.id.content, newFragment).addToBackStack(null).commitAllowingStateLoss();
    

    the completed code works well for me as bellow, hope that help

    FragmentTransaction transactionFragment = getActivity().getSupportFragmentManager().beginTransaction();
        DialogPageListFragment newFragment = new DialogPageListFragment();
        transactionFragment.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        newFragment.setArguments(extras);
        transactionFragment.add(android.R.id.content, newFragment).addToBackStack(null).commitAllowingStateLoss();
    
    0 讨论(0)
  • 2020-12-09 02:20

    Probably, the handler that is responding to the HandleMessage is associated to a destroyed activity.

    i.e.: If you rotate the screen, the old destroyed activity will handle the message, then you will call showDialog, and the exception will be thrown:

    You are creating a dialog after the old destroyed activity has called his onSaveInstanceState.

    Try replacing the callback, with the new created activity, to make sure that you are creating the dialog always in the alive activity.


    If you are not rotating, put a flag on onSaveInstance like "saving", and disabling it on onRestoreInstance. In your handleMessage method, if the flag "saving" is on, don't show the dialog, just turn on another flag indicating that the dialog must be created on onResume. Then on onResume method, check if in middle of that process, you should create the dialog, if yes, show it on onResume method.

    0 讨论(0)
  • 2020-12-09 02:20

    I was facing the same issue when post delaying Runnables handler.postDelayed(Runnable runnable, long delayed).

    I have solved the problem this way:

    1. In onSaveInstanceState I cancel the delayed tasks
    2. In onRestoreInstanceState I recreate the task if there have been delayed tasks when activity was destroyed
    0 讨论(0)
  • 2020-12-09 02:23

    too late answer but may be the correct answer. I made a parent class and and dialog fragment extends from it

     public class BaseDialogFragment extends DialogFragment {
    
    @Override
    public void show(FragmentManager manager, String tag) {
        try {
            FragmentTransaction ft = manager.beginTransaction();
            ft.add(this, tag).addToBackStack(null);
            ft.commitAllowingStateLoss();
        } catch (IllegalStateException e) {
            Log.d("ABSDIALOGFRAG", "Exception", e);
        }
    }
    
    boolean mIsStateAlreadySaved = false;
    boolean mPendingShowDialog = false;
    
    @Override
    public void onResume() {
        onResumeFragments();
        super.onResume();
    }
    
    public void onResumeFragments(){
        mIsStateAlreadySaved = false;
        if(mPendingShowDialog){
            mPendingShowDialog = false;
            showSnoozeDialog();
        }
    }
    
    @Override
    public void onPause() {
        super.onPause();
        mIsStateAlreadySaved = true;
    }
    
    private void showSnoozeDialog() {
        if(mIsStateAlreadySaved){
            mPendingShowDialog = true;
        }else{
            FragmentManager fm = getFragmentManager();
            BaseDialogFragment snoozeDialog = new BaseDialogFragment();
            snoozeDialog.show(fm, "BaseDialogFragment");
        }
    }
    

    }

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题