Назад к вопросам
Junior
82
questionbank

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

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

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 для сохранения данных состояния.