Какие знаешь способы сохранения состояния Activity?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Способы сохранения состояния Activity в Android
В Android Activity представляет собой жизненный цикл компонента, который может быть уничтожен системой для освобождения ресурсов (например, при повороте экрана, переключении приложений или нехватке памяти). Сохранение состояния необходимо для обеспечения бесшовного пользовательского опыта, чтобы данные не терялись при временном уничтожении Activity. Рассмотрим основные подходы.
1. Bundle и методы onSaveInstanceState / onRestoreInstanceState
Это базовый механизм, предоставляемый Android SDK для сохранения временных, легковесных данных. Система автоматически вызывает onSaveInstanceState() перед уничтожением Activity и передает Bundle для сохранения данных. Восстановление происходит в onCreate() или onRestoreInstanceState().
class MainActivity : AppCompatActivity() {
private var counter: Int = 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)
}
}
Особенности:
- Подходит для примитивных типов, строк, массивов и Parcelable объектов.
- Имеет ограничение по размеру (~1 МБ, но фактически рекомендуется хранить < 50 КБ).
- Данные не сохраняются после полного завершения приложения (например, через свайп из списка недавних приложений).
2. Постоянное хранилище (Persistent Storage)
Для сохранения данных, которые должны пережить перезапуск приложения, используются механизмы постоянного хранения:
- SharedPreferences – для простых ключ-значение пар (настройки, счетчики).
val prefs = getSharedPreferences("MyPrefs", MODE_PRIVATE)
// Сохранение
prefs.edit().putInt("COUNTER", counter).apply()
// Восстановление
counter = prefs.getInt("COUNTER", 0)
- База данных (Room/SQLite) – для структурированных данных, списков, сложных объектов.
- Файловая система – для больших данных, изображений, документов.
- Серверные хранилища – облачная синхронизация (Firebase, REST API).
3. Архитектурные компоненты (ViewModel + SavedStateHandle)
С появлением Android Jetpack подходы эволюционировали. ViewModel предназначен для хранения данных, связанных с UI, и переживает изменения конфигурации (например, поворот экрана). Однако стандартный ViewModel не сохраняет данные при полном уничтожении процесса. Для этого используется SavedStateHandle.
class MainViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
var counter: Int
get() = savedStateHandle.get("COUNTER_KEY") ?: 0
set(value) = savedStateHandle.set("COUNTER_KEY", value)
}
Преимущества:
- ViewModel отделяет логику данных от жизненного цикла Activity.
- SavedStateHandle автоматически сохраняет/восстанавливает данные через Bundle.
- Интеграция с Flow или LiveData для реактивного UI.
4. Создание Parcelable объектов
Для передачи сложных объектов через Bundle они должны реализовывать интерфейс Parcelable (или Serializable, но он медленнее из-за рефлексии). Современные инструменты упрощают это:
@Parcelize
data class User(val id: Int, val name: String) : Parcelable
// Сохранение в Bundle
outState.putParcelable("USER_KEY", user)
5. onRetainNonConfigurationInstance (устаревший)
Исторический метод для сохранения тяжелых объектов (например, загруженных изображений) при повороте экрана. Сейчас заменен на ViewModel, который более эффективен и интегрирован в архитектуру.
Рекомендации по выбору подхода
- Временные UI-состояния (текст в поле ввода, позиция скролла) →
onSaveInstanceState()или SavedStateHandle. - Данные, переживающие поворот экрана (списки, загруженные из сети) → ViewModel.
- Постоянные пользовательские данные (настройки, профиль) → SharedPreferences или Room.
- Крупные бинарные данные (изображения, файлы) → кэш на файловой системе с сохранением пути в Bundle.
Заключение
Современная практика сохранения состояния Activity строится на комбинации подходов: ViewModel для управления UI-данными, SavedStateHandle для сохранения через системный Bundle, и постоянные хранилища для критических данных. Важно понимать жизненный цикл Activity и выбирать метод, соответствующий типу данных и сроку их жизни, чтобы обеспечить стабильность и отзывчивость приложения.