Чем отличаются commitAllowingStateLoss и commitNowAllowingStateLoss в FragmentManager в Android
Что проверяют
Понимаете ли вы, почему транзакция фрагментов вообще падает с IllegalStateException после onSaveInstanceState, и отдаёте ли себе отчёт в том, что суффикс AllowingStateLoss не чинит проблему, а разрешает терять состояние. Заодно смотрят, различаете ли вы отложенную и немедленную транзакции.
Как отвечать
У этих методов две независимые оси, и разговор стоит начать с них.
Первая ось: когда транзакция выполнится. commit() ставит её в очередь главного потока, commitNow() выполняет синхронно, прямо в вызывающем методе.
Вторая ось: что делать, если состояние активити уже сохранено. commit() бросает исключение, а вариант с AllowingStateLoss молча выполняет транзакцию, соглашаясь на то, что в сохранённом состоянии её не окажется.
Отсюда прямой ответ: commitAllowingStateLoss это асинхронный вариант, commitNowAllowingStateLoss синхронный, и оба одинаково разрешают потерю состояния. Разница между ними только во времени выполнения.
Дальше добавьте практические следствия:
- немедленную транзакцию нельзя класть в бэкстек:
addToBackStackвместе сcommitNowдаёт исключение; commitNowвыполняется мимо очереди, поэтому его порядок с обычнымиcommitлегко перепутать; очередь разгребаетexecutePendingTransactions();AllowingStateLossуместен там, где фрагмент восстанавливать не обязательно: снять прогресс по ответу сети, пришедшему после ухода экрана в фон.
Где спотыкаются
Говорят, что эти методы избавляют от потери состояния. Наоборот: они избавляют от исключения и соглашаются на потерю. После пересоздания процесса пользователь вернётся на экран уже без этого фрагмента.
Второе: заменяют все commit на вариант с потерей состояния, чтобы убрать краши из отчётов. Падение это симптом того, что транзакция делается в неподходящей точке жизненного цикла; правильнее отложить её до момента, когда экран снова активен.
Третье: думают, что исключение бывает только из-за сохранённого состояния. Транзакции фрагментов не потокобезопасны, и вызов с фонового потока даст другую ошибку, которую суффикс уже не лечит.