Когда происходит смена конфигурации в Android-приложении

Ответ

При смене конфигурации (поворот экрана, изменение языка, размера шрифта и т.д.) система уничтожает текущую Activity и создает её заново. Это приводит к вызову:

  1. onPause()
  2. onStop()
  3. onDestroy()
  4. onCreate()
  5. onStart()
  6. onResume()

Для сохранения состояния используйте:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString("KEY", "value")
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val value = savedInstanceState?.getString("KEY")
}

Альтернативы:

  • ViewModel (сохраняется при смене конфигурации)
  • android:configChanges в манифесте (не рекомендуется)

Ответ 18+ 🔞

А, ну это же классика, ёпта! Ты представь: сидит твой активити, живёт себе спокойно, данные грузит, пользователя радует. И тут пользователь телефон просто повернул — и всё, пиздец! Система смотрит на это как на полную смену декораций и просто берёт и выносит всю твою активити к ебеням.

Всё по-честному: onPause(), onStop(), потом вообще onDestroy() — и активити накрылась медным тазом. Потом, конечно, создаётся заново: onCreate(), onStart(), onResume(). Но вся твоя промежуточная хуйня — введённый текст, выбранная позиция в списке, какой-нибудь счётчик — всё это летит в пизду, если ты заранее не позаботился. Удивление пиздец, да?

Вот чтобы не охуеть от такого поворота событий, есть старый добрый способ — onSaveInstanceState. Это как оставить записку самому себе на будущее.

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString("KEY", "value") // Кладём в карман перед смертью
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val value = savedInstanceState?.getString("KEY") // А тут проверяем карманы у нового тела
}

Работает, но это, блядь, как костыль — для простых данных сойдёт, а если у тебя там овердохуища сложных объектов, то пизда рулю.

Есть альтернативы, конечно. Первая — ViewModel. Вот это уже серьёзная тема. Эта сущность переживает поворот экрана, потому что живёт не в активити, а рядом. Засунул туда свои данные — и они не пропадут, пока активити окончательно не сдохнет. Красота!

Вторая — костыль из разряда «я сам с усами»: прописать в манифесте android:configChanges. Система увидит это и скажет: «О, чувак сам хочет рулить конфигурацией», и активити не будет убивать. Но это, я тебе скажу, путь в ад. Потому что потом тебе самому придётся вручную обрабатывать кучу событий изменения конфигурации, и доверия ебать ноль, что ты всё сделаешь правильно. Все нормальные ребята не рекомендуют так делать, только если совсем припёрло.

Короче, вывод простой: для мелких данных — Bundle, для всего остального — ViewModel. А configChanges — это для отчаянных гонщиков, которые любят себе жизнь усложнять.