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

Что произойдет с Activity при смене ориентации?

2.0 Middle🔥 221 комментариев
#UI и вёрстка#Архитектура и паттерны#Жизненный цикл и навигация

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

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

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

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

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

Последовательность вызовов методов жизненного цикла

  1. onPause() - Activity теряет фокус, но еще видна
  2. onStop() - Activity полностью скрыта
  3. onDestroy() - Activity уничтожается (вызывается обязательно!)
  4. onCreate() - создается новая Activity с новыми ресурсами
  5. onStart() - Activity становится видимой
  6. 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" />

Этот подход сложен в поддержке, так как требует ручного управления всеми изменениями ресурсов.

Рекомендации по архитектуре

  1. Разделение ответственности: используйте ViewModel для хранения данных и LiveData/Flow для наблюдения
  2. Сохранение состояния: для сложных состояний используйте SavedStateHandle в ViewModel
  3. Идемпотентность: делайте методы onCreate() и onResume() идемпотентными
  4. Асинхронные операции: используйте 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 сохраняются корректно.