Действия в 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);
}