Прежде всего, я прочитал десятки SO вопросов и прочитал отличный пост Алекса Локвуда о IllegalStateException
проблемах, связанных с транзакциями фрагментов: https://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html - tl; dr Я сделал моя домашняя работа
Но то, что я нигде не нашел, это проблема IllegalStateException
, когда экран гаснет и мы пытаемся зафиксировать транзакцию фрагмента - в моем случае покажите DialogFragment
.
То, что происходит в моем приложении, - это реакция на результат другой активности, а затем отображение DialogFragment
. Как предлагают многие пользователи SO, я не показываю диалог от onActivityResult
, но от onPostResume
(я пробовал также с onResumeFragments
) Упрощенный код выглядит следующим образом
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Timber.i("${this::class.java.simpleName} onActivityResult")
activityResult = ActivityResult(this::class, requestCode, resultCode, data)
}
override fun onPostResume() {
super.onPostResume()
Timber.i("${this::class.java.simpleName} onPostResume")
activityResult?.let { ActivityResultRepository.resultsSubject.onNext(it) }
}
override fun onResumeFragments() {
super.onResumeFragments()
Timber.i("${this::class.java.simpleName} onResumeFragments")
}
Мне не удалось воспроизвести исключение на моем устройстве (Mate 20 pro) или на эмуляторе, но я получаю отчеты о сбоях от пользователей моего приложения (затронуто 0,5% пользователей)
Я предполагаю, что мое приложение пытается показать диалоговое окно после выключения экрана. Отключение экрана - это произвольное событие, которое вызывает метод onSaveInstanceState
и может вызываться прямо перед моим onPostResume
методом. Однако это только мое предположение !, может быть, есть и другая причина исключения
Кто-нибудь сталкивался с подобными проблемами и сумел их решить? Я знаю, что могу использовать commitAllowingStateLoss
, но, во-первых, метод show
из DialogFragment
не позволяет этого сделать, придется показывать диалог вручную с помощью FragmentManager
(не знаю, есть ли какие-либо последствия), во-вторых, commitAllowingStateLoss
вообще плохо делать
Я добавляю отчет о сбое, хотя все уже видели его где-то:)
Caused by java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2053)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2079)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:632)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:143)