Что произойдет с Activity при смене ориентации?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Жизненный цикл Activity при смене ориентации
При смене ориентации устройства (например, с портретной на ландшафтную) система Android полностью уничтожает текущую Activity и создает ее заново. Это происходит потому, что система загружает альтернативные ресурсы (разные макеты, строки, размеры) из соответствующих папок res/layout-land/, res/values-land/ и т.д., что требует пересоздания Activity для применения новых ресурсов.
Последовательность вызовов методов жизненного цикла
- onPause() - Activity теряет фокус, но еще видна
- onStop() - Activity полностью скрыта
- onDestroy() - Activity уничтожается (вызывается обязательно!)
- onCreate() - создается новая Activity с новыми ресурсами
- onStart() - Activity становится видимой
- onResume() - Activity получает фокус и готова к взаимодействию
Ключевые проблемы и их решения
Проблема 1: Потеря данных состояния UI Значения в полях ввода, позиция прокрутки, временные данные теряются при пересоздании.
Решение: Использование onSaveInstanceState() и onRestoreInstanceState()
class MainActivity : AppCompatActivity() {
private var userInput: String = ""
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("USER_INPUT", userInput)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
userInput = savedInstanceState.getString("USER_INPUT", "")
// Восстанавливаем UI с сохраненными данными
}
}
Проблема 2: Перезапуск тяжелых операций Загрузка данных из сети, выполнение сложных вычислений будут запускаться заново.
Решение: Сохранение в ViewModel или использование retainInstance для Fragment
class UserViewModel : ViewModel() {
val userData: MutableLiveData<List<User>> = MutableLiveData()
fun loadUsers() {
// Данные сохраняются при смене ориентации
viewModelScope.launch {
val users = repository.getUsers()
userData.postValue(users)
}
}
}
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: UserViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
viewModel.userData.observe(this) { users ->
// Обновление UI
}
}
}
Альтернативные подходы
1. Фиксация ориентации в манифесте:
<activity
android:name=".MainActivity"
android:screenOrientation="portrait" />
Не рекомендуется, так как ограничивает пользовательский опыт.
2. Обработка конфигурации самостоятельно:
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Самостоятельное обновление ресурсов
}
Требует объявления в манифесте:
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize" />
Этот подход сложен в поддержке, так как требует ручного управления всеми изменениями ресурсов.
Рекомендации по архитектуре
- Разделение ответственности: используйте ViewModel для хранения данных и LiveData/Flow для наблюдения
- Сохранение состояния: для сложных состояний используйте
SavedStateHandleв ViewModel - Идемпотентность: делайте методы
onCreate()иonResume()идемпотентными - Асинхронные операции: используйте
CoroutineScopeилиWorkManagerдля длительных операций
Оптимизация производительности
// Использование ViewBinding для быстрого доступа к view
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Инициализация происходит только один раз при создании
initRecyclerView()
setupObservers()
}
При правильной реализации архитектуры с использованием ViewModel, LiveData и сохранением состояния, смена ориентации становится практически незаметной для пользователя, а данные и состояние UI сохраняются корректно.