Как сохранить состояние при смене конфигурации
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Сохранение состояния при смене конфигурации в Android
Сохранение состояния при смене конфигурации (например, поворот экрана) — одна из фундаментальных задач в разработке Android-приложений. При смене конфигурации система по умолчанию уничтожает и пересоздает активити, что может привести к потере пользовательских данных, если не предпринять специальных мер. Рассмотрим основные подходы и лучшие практики.
Основные механизмы сохранения состояния
1. onSaveInstanceState() и onRestoreInstanceState()
Базовый механизм для сохранения временных данных. Подходит для небольших объемов данных (примитивные типы, Parcelable объекты).
class MainActivity : AppCompatActivity() {
private var counter = 0
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("COUNTER_KEY", counter)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
counter = savedInstanceState.getInt("COUNTER_KEY", 0)
}
}
2. ViewModel + SavedStateHandle
Современный рекомендуемый подход, который отделяет логику сохранения состояния от жизненного цикла UI компонентов.
class MainViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
companion object {
private const val COUNTER_KEY = "counter_key"
}
val counter: LiveData<Int> = savedStateHandle.getLiveData(COUNTER_KEY, 0)
fun incrementCounter() {
savedStateHandle[COUNTER_KEY] = (counter.value ?: 0) + 1
}
}
Продвинутые стратегии
Разделение по типам данных:
- Постоянные данные — сохраняются в базу данных, SharedPreferences или файлы
- Временные данные сессии — сохраняются через ViewModel или onSaveInstanceState
- Восстанавливаемые ресурсы — загружаются заново при создании активити
Использование архитектурных компонентов:
@Composable
fun CounterScreen(
viewModel: CounterViewModel = viewModel()
) {
val counter by viewModel.counter.collectAsState()
Column {
Text(text = "Count: $counter")
Button(onClick = { viewModel.increment() }) {
Text("Increment")
}
}
}
Рекомендации и лучшие практики
-
Используйте ViewModel как основной инструмент для хранения UI-состояния — он переживает смену конфигурации.
-
Различайте конфигурационные изменения и реальное уничтожение процесса:
- Для сохранения при уничтожении процесса используйте
onSaveInstanceState() - Для смены конфигурации достаточно ViewModel
- Для сохранения при уничтожении процесса используйте
-
Избегайте сохранения тяжелых объектов в Bundle — используйте идентификаторы и перезагружайте данные.
-
Для сложных UI состояний комбинируйте несколько подходов:
- ViewModel для бизнес-логики
- SavedStateHandle для восстановления после смерти процесса
- Локальная база данных для постоянных данных
-
Тестируйте сценарии:
// Включение смены конфигурации в эмуляторе adb shell am broadcast -a com.android.intent.action.SET_TEST_CONFIGURATION
Распространенные ошибки
- Слишком много данных в Bundle — приводит к TransactionTooLargeException
- Игнорирование смерти процесса — только смена конфигурации покрывается ViewModel
- Смешивание логики восстановления и бизнес-логики — нарушает принцип единственной ответственности
Ключевой принцип: проектируйте архитектуру так, чтобы восстановление состояния было естественной частью жизненного цикла компонентов, а не "костылем". Современные подходы с ViewModel, SavedStateHandle и архитектурой MVVM/MVI позволяют создавать устойчивые к изменениям конфигурации приложения с чистым и поддерживаемым кодом.