Sobes.tech
Back to questions
Junior
153
questionbank

Почему происходит пересоздание активности при повороте экрана?

Answer from AI

sobes.tech AI

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

Жизненный цикл активности при повороте:

  1. onPause()
  2. onStop()
  3. onDestroy()
  4. Система создает новый экземпляр активности.
  5. onCreate()
  6. onStart()
  7. onResume()

Для сохранения данных состояния перед уничтожением активности используются:

  • onSaveInstanceState(): сохраняет небольшие данные в Bundle.

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("myKey", "myValue") // Сохраняем данные
    }
    

    Восстановление в onCreate() или onRestoreInstanceState():

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        if (savedInstanceState != null) {
            val myValue = savedInstanceState.getString("myKey") // Восстанавливаем данные
        }
        // ...
    }
    
  • ViewModel: Сохраняет данные в течение всего жизненного цикла UI-контроллера (Activity/Fragment), даже при изменении конфигурации. ViewModel переживает уничтожение активности и не теряет свое состояние.

    class MyViewModel : ViewModel() {
        var counter = 0
    }
    

    Использование в активности/фрагменте:

    class MyActivity : AppCompatActivity() {
        private lateinit var viewModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
            // Теперь viewModel.counter сохраняется при повороте
        }
    }
    
  • Сохранение данных в SharedPreferences или базе данных для более персистентных данных.

Чтобы избежать пересоздания активности при повороте экрана, можно объявить, что активность самостоятельно обрабатывает изменения конфигурации. Это делается в манифесте, добавляя configChanges="orientation|screenSize|screenLayout" атрибут к тегу <activity>:

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|screenLayout">
</activity>

В этом случае вместо пересоздания активности будет вызван метод onConfigurationChanged():

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Обработка изменения конфигурации вручную
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Логика для ландшафтной ориентации
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // Логика для портретной ориентации
    }
}

Использование configChanges не рекомендуется в большинстве случаев, так как может привести к сложностям в управлении состоянием и ресурсами при различных изменениях конфигурации. Предпочтительный подход – использовать ViewModel для сохранения данных состояния.