Действия в onActivityResult и "Ошибка Не удается выполнить это действие после onSaveInstanceState"

Реализация приложения, в котором пользователь может войти в систему. У меня есть следующая ситуация: если пользователь вошел в систему, выполните действие else, запустив операцию входа для результата, и если результат Activity.RESULT_OK выполнит действие.

Моя проблема в том, что действие для выполнения - это показать DialogFragment, но вызывать

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

в обратном вызове onActivityResult выдается исключение:

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

Итак, как я могу это решить? Я думаю, что поднимаю флаг там и показываю диалог в onResume, но я вижу это решение немного грязным

Изменить: добавлено больше кода (Im, следующего за этим примером для показа DialogFragment

Когда действие запрашивается пользователем:

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

В том же фрагменте

@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")
    }
}

И если пользователь регистрирует вызовы активности входа,

setResult(Activity.RESULT_OK);
finish();

Ответ 1

Лучшее, что я придумал, это не использовать .show(), а скорее сделать это.

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

Ответ 2

Вот обходной путь, который отлично подходит для меня.

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);
        }
    });        
}

Ответ 3

Если использовать DialogFragment, единственное, что сработало для меня, - это отбросить фрагмент с помощью dissmissAllowingStateLoss()

Ответ 4

Я просто проверяю, уничтожается ли действие.

if (!getActivity().isFinishing()) {
    DialogFragment fragment = MyFragment.newInstance();
    fragment.show(getActivity().getSupportFragmentManager(), MyFragment.TAG);
}

Ответ 5

Переопределить функцию show(Fragment manager, String tag), разрешив потерять состояние и изменить mDismissed = false; mShownByMe = true; из функции origibal путем отражения:

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();
    }
}

Ответ 6

Настоящие работы.

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

Но все же плохо, потому что получена ошибка "Активность была уничтожена"

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

Итак, мое решение добавляет 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();
                    }
                }

при увольнении:

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();
            }
        }

Ответ 7

Это исключение генерируется всякий раз, когда a FragmentTrasaction совершается после того, как FragmentManager сохранил свое состояние. Легкий и чистый способ - проверить, действительно ли FragmentManager уже сохранили состояние перед показом DialogFragment.

if(!getSupportFragmentManager.isStateSaved()) {
    MyDialogFragment dialogFragment = new MyDialogFragment()
    dialogFragment.show(getSupportFragmentManager, TAG);
}