← Назад к вопросам

Какие методы жизненного цикла вызываются при смене ориентации экрана?

1.6 Junior🔥 191 комментариев
#Android компоненты#Жизненный цикл и навигация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Методы жизненного цикла при смене ориентации экрана

При изменении ориентации экрана устройства (например, с portrait на landscape) Android воспринимает это как значительное изменение конфигурации системы. Если активити не обрабатывает это изменение самостоятельно, система уничтожает текущую активити и создает ее новую инстанцию, что приводит к полному проходу по жизненному циклу. Вот последовательность вызываемых методов, от момента начала поворота до завершения создания новой активити.

Полная последовательность вызовов (при стандартной обработке)

  1. onPause() — вызывается первым. Активность частично теряет фокус, но остается видимой. Здесь следует сохранять легковесные данные или остановить операции, которые не должны выполняться в фоне.

  2. onStop() — активити полностью скрывается. Процесс уничтожения начинается.

  3. onDestroy() — завершающий метод уничтожения текущей инстанции активити. Все ресурсы должны быть освобождены.

  4. onCreate() — система создает новую инстанцию активити. Здесь происходит инициализация UI, восстановление данных из Bundle (если они были сохранены).

  5. onStart() — активити становится видимой, но еще не взаимодействует с пользователем.

  6. onResume() — активити полностью активна и готов к взаимодействию. Это завершение процесса восстановления.

Ключевой механизм сохранения состояния: onSaveInstanceState()

Перед уничтожением активити, между onPause() и onStop(), система гарантированно вызывает метод onSaveInstanceState(Bundle outState). Это критически важный метод для сохранения временных данных UI (например, текст в EditText, позиция в списке, прогресс игры).

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    // Сохраняем текущий текст из EditText
    outState.putString("EDIT_TEXT_KEY", myEditText.text.toString())
    // Сохраняем позицию в RecyclerView
    outState.putInt("SCROLL_POSITION", recyclerView.layoutManager?.firstVisibleItemPosition ?: 0)
}

При создании новой активити в onCreate() этот Bundle передается как параметр savedInstanceState.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    if (savedInstanceState != null) {
        // Восстанавливаем текст
        val savedText = savedInstanceState.getString("EDIT_TEXT_KEY")
        myEditText.setText(savedText)
        // Восстанавливаем позицию прокрутки
        val savedPosition = savedInstanceState.getInt("SCROLL_POSITION")
        recyclerView.layoutManager?.scrollToPosition(savedPosition)
    }
}

Оптимизация и предотвращение полного пересоздания

Если полный пересоздание активити с восстановлением состояния является ресурсоемким или приводит к потере данных (например, крупные списки, тяжелые вычисления), можно управлять этим процессом двумя способами:

  • Фиксирование ориентации в манифесте: Простой способ, но ограничивает UX.

    <activity
        android:name=".MyActivity"
        android:screenOrientation="portrait" />
    
  • Самостоятельная обработка изменения конфигурации: Реализация метода onConfigurationChanged() и указание, какие изменения активити будет обрабатывать самостоятельно.

    *   В манифесте объявляем, какие конфигурации активити обрабатывает само:
    ```xml
    <activity
        android:name=".MyActivity"
        android:configChanges="orientation|screenSize" />
    ```
    *   В активити переопределяем метод:
    ```kotlin
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        // Здесь можно программно перестроить layout,
        // например, изменить расположение элементов, без пересоздания активити.
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // Адаптировать UI для landscape
            recyclerView.layoutManager = GridLayoutManager(this, 3)
        } else {
            // Адаптировать UI для portrait
            recyclerView.layoutManager = LinearLayoutManager(this)
        }
    }
    ```
    В этом случае полный цикл уничтожения/создания **не выполняется**. Вызываются только `onConfigurationChanged()` и, возможно, `onPause()`/`onResume()` в зависимости от ситуации. Однако, подход требует более сложной ручной логики адаптации UI.

Итог: Стандартная реакция на поворот — полный цикл onPause() -> onSaveInstanceState() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResume(). Метод onSaveInstanceState() и его парный onRestoreInstanceState() (вызываемый после onStart()) являются центральными для сохранения пользовательского состояния. Для сложных случаев применяется самостоятельная обработка через configChanges.