запуске приложения в container посредством replace сеттится фрагмент со сплешом. Сплеш забирает данные с апи, кеширует их и даёт команду на отображение фрагмента с контентом, который сеттится аналогично через replace.
Есть такой кейс, что если запустить апку и сразу её свернуть, а затем развернуть через какое - то время (т.е дождаться пока сплеш прогрузит данные и даст команду на переход), то я упаду с:
java.lang.IllegalStateException: FragmentManager is already executing transactions
Я это пофиксил. Я пользуюсь своим на коленке написанным навигатором, который который сеттит фрагменты используя commitNow(). Апка перестала падать, когда я заменил commitNow() на commitAllowingStateLoss().
Однако я нихрена не понял что произошло, объясните пж.
Как ни странно, мой кейс нифига не гуглится. Поэтому приходится думать головой, а эт чёт сложно.
Я знаю, что commitNow() - синхронный, а commitAllowingStateLoss() - ассинхронный. Но мне это не говорит ни о чём. В теории, мб есть какая - то связь с тем что приложение свёрнуто и тем что вызов был именно синхронный, но чёт сомнения одолевают. В доках ничего явно не сказано на этот счёт.
Я залез чуть глубже, и увидел что этот эксепшн бросает FragmentManager ручками. Вот блок кода:
private void ensureExecReady(boolean allowStateLoss) {
if (mExecutingActions) {
throw new IllegalStateException("FragmentManager is already executing transactions");
}
Логика там вроде как примерно такая: запускается транзакция, флаг сеттится в true, транзакция завершается, флаг сеттится в false. Это предположение, т.к отдебажить это я не могу - дебаггер слетает когда я апку сворачиваю, а то что я успеваю отдебажить - это ад, там этот флаг 100500 раз дёргается, нифига не понятно.
Собственно, догадок покамест нет. Моя транзакция по установке сплеша завершается успешно(скорее всего), т.к я его вижу прежде чем апку свернуть.
Шо происходет?
В моём коде нет ничего интересного, но пущай будет.
fun replaceNewFragment(screen: Screen, animationType: AnimationType? = null) {
fragmentManager
.beginTransaction()
.setCustomAnimations(R.anim.anim1,R.anim.anim2)
.replace(container, screen.getFragment(), screen.getTag())
.commitNow()
}
приложение сворачивалось кнопкой back? если да, то вызвался onDestroy, активити умерла. ФрагментМенеджеру стало некуда втыкать фрагмент. Именно для этих целей и используется асинхронный коммит.
Обсуждают сегодня