Некоторые пользователи сообщают, что если они воспользуются быстрым действием на панели уведомлений, они приближаются к силе.
Я показываю быстрое действие в уведомлении, которое вызывает класс TestDialog . В классе TestDialog после нажатия кнопки «отложить» я покажу SnoozeDialog.
private View.OnClickListener btnSnoozeOnClick() {
return new View.OnClickListener() {
public void onClick(View v) {
showSnoozeDialog();
}
};
}
private void showSnoozeDialog() {
FragmentManager fm = getSupportFragmentManager();
SnoozeDialog snoozeDialog = new SnoozeDialog();
snoozeDialog.show(fm, "snooze_dialog");
}
Ошибка *IllegalStateException: Can not perform this action after onSaveInstanceState*.
Строка кода, в которой запускается исключение IllegarStateException:
snoozeDialog.show(fm, "snooze_dialog");
Класс расширяет «FragmentActivity», а класс «SnoozeDialog» расширяет «DialogFragment».
Вот полная трассировка стека ошибки:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
at com.test.testing.TestDialog.f(TestDialog.java:538)
at com.test.testing.TestDialog.e(TestDialog.java:524)
at com.test.testing.TestDialog.d(TestDialog.java:519)
at com.test.testing.g.onClick(TestDialog.java:648)
at android.view.View.performClick(View.java:3620)
at android.view.View$PerformClick.run(View.java:14292)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
Я не могу воспроизвести эту ошибку, но получаю много сообщений об ошибках.
Кто-нибудь может помочь, как я могу исправить эту ошибку?
Ответы:
Это обычная проблема . Мы решили эту проблему, переопределив show () и обработав исключение в расширенном классе DialogFragment.
Обратите внимание, что применение этого метода не изменит внутренние поля DialogFragment.class:
В некоторых случаях это может привести к неожиданным результатам. Лучше использовать commitAllowingStateLoss () вместо commit ()
источник
Это означает, что вы
commit()
(show()
в случае DialogFragment) фрагмент послеonSaveInstanceState()
.Android сохранит состояние вашего фрагмента в
onSaveInstanceState()
. Итак, если выcommit()
фрагментируете послеonSaveInstanceState()
фрагмента, состояние будет потеряно.В результате, если Activity будут убиты и воссозданы позже, фрагмент не будет добавлен к Activity, что плохо для пользователя. Вот почему Android не допускает потери состояния любой ценой.
Простое решение - проверить, сохранено ли уже состояние.
Примечание: onResumeFragments () будет вызываться, когда фрагменты возобновятся.
источник
ссылка: ссылка
источник
Через несколько дней я хочу поделиться своим решением , как я установил его, чтобы показать DialogFragment Вам необходимо переопределить
show()
метод его и вызватьcommitAllowingStateLoss()
наTransaction
объект. Вот пример на Котлине:источник
DialogFragment
вы могли бы изменить это функция расширения Котлин со следующей подписью:fun DialogFragment.showAllowingStateLoss(fragmentManager: FragmentManager, tag: String)
. Кроме того, try-catch не требуется, поскольку вы вызываетеcommitAllowingStateLoss()
метод, а неcommit()
метод.Если диалог не очень важен (нормально не показывать его, когда приложение закрыто / больше не отображается), используйте:
И открывать свой диалог (фрагмент) только тогда, когда мы выполняем:
ИЗМЕНИТЬ, ВОЗМОЖНО ЛУЧШЕЕ РЕШЕНИЕ:
Когда onSaveInstanceState вызывается в жизненном цикле, это непредсказуемо, я думаю, что лучшим решением будет проверить isSavedInstanceStateDone () следующим образом:
источник
Я сталкивался с этой проблемой годами.
Интернет завален десятками (сотнями? Тысячами?) Дискуссий по этому поводу, и путаницы и дезинформации в них, кажется, предостаточно.
Чтобы усугубить ситуацию, и в духе комикса xkcd «14 стандартов» я бросаю свой ответ на ринг.
cancelPendingInputEvents()
,commitAllowingStateLoss()
,catch (IllegalStateException e)
, И другие подобные решения , все , кажется , зверские.Надеюсь, следующее легко показывает, как воспроизвести и исправить проблему:
источник
попробуйте использовать FragmentTransaction вместо FragmentManager. Я думаю, что приведенный ниже код решит вашу проблему. Если нет, дайте мне знать.
РЕДАКТИРОВАТЬ:
Фрагмент транзакции
Пожалуйста, проверьте эту ссылку. Я думаю, это решит ваши вопросы.
источник
Использование новых областей жизненного цикла Activity-KTX так же просто, как следующий пример кода:
Этот метод может быть вызван непосредственно после onStop () и будет успешно отображать диалог после вызова onResume () после возврата.
источник
Многие представления публикуют высокоуровневые события, такие как обработчики кликов, в очередь событий для отложенного запуска. Итак, проблема в том, что «onSaveInstanceState» уже был вызван для Activity, но очередь событий содержит отложенное «событие щелчка». Следовательно, когда это событие отправляется вашему обработчику
и ваш код вызывает
show
исключение IllegalStateException.Самое простое решение - очистить очередь событий в
onSaveInstanceState
источник
activity
иfragment
).Сделайте объект фрагмента диалога глобальным и вызовите dismissAllowingStateLoss () в методе onPause ()
Не забудьте указать значение во фрагменте и вызвать show () при нажатии кнопки или где-либо еще.
источник
Хотя официально это нигде не упоминается, но я сталкивался с этой проблемой пару раз. По моему опыту, что-то не так в библиотеке совместимости, поддерживающей фрагменты на старых платформах, что вызывает эту проблему. Вы можете проверить это с помощью обычного API-интерфейса диспетчера фрагментов. Если ничего не работает, вы можете использовать обычный диалог вместо фрагмента диалога.
источник
Используйте метод showAllowingStateLoss вместо show
Наслаждаться ;)
источник
StatelessDialogFragment
внутрь одного из своих пакетов. Спасибо, чувак. Я скоро протестирую его в продакшене.используйте этот код
вместо того
источник
Я нашел элегантное решение этой проблемы с помощью отражения. Проблема всех вышеперечисленных решений в том, что поля mDismissed и mShownByMe не меняют своего состояния.
Просто переопределите метод "show" в собственном настраиваемом фрагменте диалогового окна нижнего листа, как в примере ниже (Kotlin)
источник
Следующая реализация может использоваться для решения проблемы безопасного выполнения изменений состояния в течение
Activity
жизненного цикла, в частности для отображения диалогов: если состояние экземпляра уже было сохранено (например, из-за изменения конфигурации), оно откладывает их до тех пор, пока возобновленное состояние не изменится. было выполнено.Затем используйте такой класс:
Вы можете безопасно отображать диалоги, не беспокоясь о состоянии приложения:
а затем позвоните
TestDialog.show(this)
из вашегоXAppCompatActivity
.Если вы хотите создать более общий класс диалогового окна с параметрами, вы можете сохранить их в
Bundle
с аргументами вshow()
методе и извлекать ихgetArguments()
вonCreateDialog()
.Весь подход может показаться немного сложным, но как только вы создали два базовых класса для действий и диалогов, он довольно прост в использовании и отлично работает. Его можно использовать для других
Fragment
операций, на которые может повлиять та же проблема.источник
Эта ошибка возникает из-за того, что события ввода (такие как нажатие клавиши или события onclick) доставляются после
onSaveInstanceState
вызова.Решение состоит в том, чтобы переопределить
onSaveInstanceState
вашу Activity и отменить любые ожидающие события.источник