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

Как обрабатывать изменения конфигурации в Android?

1.0 Junior🔥 191 комментариев
#Работа с данными

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

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

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

Как обрабатывать изменения конфигурации в Android

Обработка изменений конфигурации — критически важная часть разработки Android приложений, поскольку система Android динамично управляет жизненным циклом компонентов при изменении параметров устройства, таких как ориентация, язык, размер окна (в multi-window режиме) или доступность ресурсов.

Механизм изменения конфигурации и его последствия

При изменении конфигурации (например, повороте устройства) система Android по умолчанию уничтожает текущий Activity и создает его новый экземпляр, вызывая полный цикл onDestroy() -> onCreate(). Это позволяет системе автоматически перезагрузить ресурсы (layouts, strings), адаптированные к новой конфигурации. Однако это приводит к потере состояния UI и данных, которые не были сохранены.

Для сохранения состояния используются следующие механизмы:

1. Сохранение состояния через onSaveInstanceState()

Это базовый подход для сохранения временного UI состояния (например, текста в EditText, позиции списка).

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString("EDIT_TEXT_KEY", editText.text.toString())
    outState.putInt("LIST_POSITION_KEY", recyclerView.layoutManager?.firstVisibleItemPosition ?: 0)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (savedInstanceState != null) {
        val savedText = savedInstanceState.getString("EDIT_TEXT_KEY")
        editText.setText(savedText)
    }
}

Bundle имеет ограничения по размеру и не предназначен для сохранения сложных объектов (например, изображений).

2. Сохранение данных в ViewModel

ViewModel — компонент архитектуры Android Jetpack, который специально разработан для хранения и управления UI-данными, устойчивыми к изменениям конфигурации. ViewModel не уничтожается при пересоздании Activity/Fragment.

class MyViewModel : ViewModel() {
    private val _userList = MutableLiveData<List<User>>()
    val userList: LiveData<List<User>> = _userList

    fun loadUsers() {
        // Загрузка данных из репозитория
    }
}

// В Activity/Fragment
private val viewModel: MyViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel.userList.observe(this, { users ->
        // Обновить UI, данные сохранятся при повороте
    })
}

3. Локальное сохранение в базу данных или SharedPreferences

Для персистентных данных, которые должны сохраняться между сессиями приложения, используйте Room, SharedPreferences или файловое хранилище.

// Пример с Room
@Entity
data class User(val name: String, val age: Int)

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): Flow<List<User>>
}

// Данные будут сохраняться после изменения конфигурации

4. Обработка через android:configChanges в манифесте

Вы можете объявить в манифесте, что Activity будет самостоятельно обрабатывать определенные изменения конфигурации, без пересоздания. Это требует ручной адаптации ресурсов.

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|locale">

Затем в Activity нужно переопределить onConfigurationChanged():

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Например, перезагрузить layout для новой ориентации
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        setContentView(R.layout.activity_landscape)
    } else {
        setContentView(R.layout.activity_portrait)
    }
}

⚠️ Важно: Использование configChanges считается продвинутым подходом и не рекомендуется для большинства случаев, поскольку вы берете на себя ответственность за обработку всех объявленных изменений, что может привести к сложным багам, если реализация неполная.

5. Сохранение состояния в Fragments

Для Fragment также доступен onSaveInstanceState(), но более эффективно использовать ViewModel совместно с Fragment или сохранять состояние в родительском Activity.

Рекомендации по выбору стратегии

  • Для временного UI состояния (скрытые/развернутые панели, позиции прокрутки) используйте onSaveInstanceState() или SavedStateHandle в ViewModel.
  • Для данных, связанных с UI (списки, результаты сетевых запросов) обязательно используйте ViewModel.
  • Для персистентных данных (настройки пользователя, кэш) используйте Room, DataStore или SharedPreferences.
  • Избегайте использования android:configChanges для простых случаев типа изменения ориентации — система Android эффективно справляется с этим самостоятельно. Используйте этот атрибут только для специализированных сценариев (например, приложения с кастомным управлением размером окна).

Комбинация ViewModel + onSaveInstanceState() (или SavedStateHandle) + персистентное хранилище покрывает большинство потребностей, обеспечивая устойчивый и удобный пользовательский опыт при любых изменениях конфигурации устройства.