Какие проблемы могут возникнуть из-за синхронности или асинхронности commit
Что проверяют
Речь почти всегда о SharedPreferences.Editor: знаете ли вы разницу между commit() и apply() и цену каждого варианта. Иногда то же спрашивают про FragmentTransaction, поэтому уточнить, о каком commit речь, само по себе плюс. Следом спрашивают, чем SharedPreferences заменить сегодня.
Как отвечать
Про SharedPreferences:
commit(): синхронная запись на диск, возвращаетbooleanоб успехе. На главном потоке это дисковый I/O в UI: подтормаживания, нарушения StrictMode, на медленной памяти риск ANR;apply(): сразу меняет данные в памяти, а на диск пишет в фоне и результата не возвращает. Если процесс убьют до записи, изменение потеряется;- скрытая синхронность
apply(): незаконченные записи копятся вQueuedWork, и система дожидается их при остановке активити и в жизненном цикле сервисов. Частыеapply()с крупным файлом дают ANR именно на переходах между экранами.
Про фрагменты: commit() у транзакции асинхронный, он лишь планирует выполнение на главном потоке, и сразу после вызова фрагмент ещё не добавлен. commitNow() выполняется синхронно, но несовместим с addToBackStack(). commit() после onSaveInstanceState бросает IllegalStateException, а commitAllowingStateLoss() обходит это ценой потери состояния.
Современный ответ: для настроек Google рекомендует Jetpack DataStore. Запись идёт через suspend-функцию edit {} транзакционно и вне главного потока, чтение через Flow, так что выбор между commit и apply исчезает сам.
Где спотыкаются
Называют apply() полностью безопасным. Про ожидание QueuedWork в onStop знают немногие, а это частая причина ANR в отчётах Play Console.
Вызывают commit() на главном потоке ради возвращаемого boolean и потом никак его не проверяют.
Хранят в SharedPreferences большие JSON. Файл целиком читается в память при первом обращении, и первое чтение с главного потока ждёт окончания этой загрузки.