Есть много связанных проблем с похожим сообщением об ошибке.Проверьте вторую строку этой конкретной трассировки стека.Это исключение конкретно относится к вызову FragmentManagerImpl.popBackStackImmediate
.
Этот вызов метода, например popBackStack
, будет всегда завершаться с ошибкой IllegalStateException
, если состояние сеанса уже было сохранено.Проверьте источник.Вы ничего не можете сделать, чтобы остановить это исключение.
- Удаление звонка на
super.onSaveInstanceState
не поможет. - Создание фрагмента с помощью
commitAllowingStateLoss
не поможет.
Вот как я наблюдал проблему:
- Есть форма с кнопкой отправки.
- При нажатии кнопки создается диалоговое окно и запускается асинхронный процесс.
- Пользователь нажимает клавишу home до завершения процесса - вызывается
onSaveInstanceState
. - Процесс завершается, выполняется обратный вызов и предпринимается попытка
popBackStackImmediate
. IllegalStateException
.
Вот что я сделал, чтобы решить эту проблему:
Поскольку невозможно избежать IllegalStateException
в обратном вызове, поймайте и проигнорируйте его.
try {
activity.getSupportFragmentManager().popBackStackImmediate(name);
} catch (IllegalStateException ignored) {
// There's no way to avoid getting this if saveInstanceState has already been called.
}
Этого достаточно, чтобы остановить сбой приложения.Но теперь пользователь восстановит приложение и увидит, что кнопка, которую, как они думали, нажали, вообще не была нажата (они думают).Фрагмент формы все еще показывает!
Чтобы исправить это, когда диалоговое окно создано, создайте некоторое состояние, чтобы указать, что процесс запущен.
progressDialog.show(fragmentManager, TAG);
submitPressed = true;
И сохраните это состояние в комплекте.
@Override
public void onSaveInstanceState(Bundle outState) {
...
outState.putBoolean(SUBMIT_PRESSED, submitPressed);
}
Не забудьте снова загрузить его в onViewCreated
Затем, при возобновлении, откатить фрагменты, если ранее была предпринята попытка отправки.Это не позволяет пользователю вернуться к тому, что выглядит как неподтвержденная форма.
@Override
public void onResume() {
super.onResume();
if (submitPressed) {
// no need to try-catch this, because we are not in a callback
activity.getSupportFragmentManager().popBackStackImmediate(name);
submitPressed = false;
}
}