IllegalStateException - библиотека поддержки фрагментов

У меня есть серьезная проблема с тем, что мое приложение постоянно сбой на некоторых пользовательских устройствах со следующим исключением в методе Activity onStart:

Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:123) 

Я не могу воспроизвести эту ошибку локально в своем эмуляторе. Я нашел несколько вопросов относительно этой проблемы в stackoverflow: здесь и здесь

Я попробовал предложенное решение, то есть не допускал пустых пакетов в onSaveInstance ни в фрагментах, ни в действиях.

Однако проблема остается. Это единственный отчет Crash, который я когда-либо получал, и я получаю его непрерывно.

Есть ли у кого-нибудь рабочее решение?

Ответ 1

Я решил эту проблему с помощью

  • обновление моей поддержки lib до версии 10
  • используя обходное решение, опубликованное здесь: http://code.google.com/p/android/issues/detail?id=23096 i.e.. Добавьте фрагмент non-ui в onResumeFragments и вызовите дальнейшие транзакции в обратном вызове Listener.

Проверьте мой ответ здесь для кода: "Невозможно выполнить это действие после onSaveInstanceState" - Почему я получаю это исключение из метода onResume моей деятельности?

Больше не осталось исключений IllegalStateException.

Ответ 3

Читать эту статью.

и

Этот.

Как только проблема будет понята, выполните правильные действия:

Укажите, почему ваши транзакции происходят за пределами вашего onResume. Почему это происходит, когда их не должно быть. Почему вы вручную добавляете и удаляете фрагменты в отношении жизненного цикла вашего приложения, а не когда пользователь запрашивает. Возможно, вам понадобится один раз в onCreate() или когда пользователь что-то вызывает. Но почему вы возитесь с ними в onResume() в первую очередь? Не делай этого.

Если вы измените все .commit() на .commitAllowStateLoss(), тогда сбой исчезнет. Но тебе лучше не делать этого. Вам лучше убедиться, что вы никогда не изменяете свои фрагменты, кроме случаев, когда приложение полностью вживлено. Иногда это означает, что вы никогда не загружаете фрагмент из OnActivityResult(), а скорее помечены для запуска в вашем onPostResume() и избегаете выполнения изменений пользовательского интерфейса в асинхронных потоках, которые ошибочно предполагают, что вы не могли убить активность за это время.

Если вы хотите просто закрыть все, .commitAllowStateLoss() сделает это. Если вы хотите сделать это правильно, убедитесь, что вы не возитесь со своими фрагментами после того, как все умрет.