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

Что такое ViewModel в Android? Какие её свойства и для чего она используется?

1.7 Middle🔥 262 комментариев
#Архитектура и паттерны#Жизненный цикл и навигация

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

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

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

📱 ViewModel в Android: архитектурный компонент для управления данными UI

ViewModel — это класс из библиотеки Android Architecture Components (Jetpack), предназначенный для хранения и управления данными, связанными с пользовательским интерфейсом (UI), таким образом, чтобы эти данные переживали изменения конфигурации (например, поворот экрана). Он работает в связке с жизненным циклом (Lifecycle) активити или фрагмента, но не зависит от них напрямую, что позволяет избежать утечек памяти и потери состояния.

🎯 Основные свойства ViewModel

  1. Сохраняемость при изменении конфигурации: Данные в ViewModel не уничтожаются при повороте устройства или других изменениях конфигурации. Это ключевое отличие от хранения данных в самом активити/фрагменте.
  2. Привязанность к жизненному циклу: ViewModel привязана к LifecycleOwner (обычно Activity или Fragment). Она существует, пока соответствующий Scope (область видимости) активити/фрагмента не будет окончательно завершён (не просто остановлен, а уничтожен).
  3. Отделение логики от UI: ViewModel не содержит ссылок на View-элементы (TextView, Button и т.д.), что способствует чистой архитектуре и упрощает unit-тестирование.
  4. Эффективная работа с данными: Часто используется вместе с LiveData или StateFlow/SharedFlow для создания реактивных UI, которые автоматически обновляются при изменении данных.

🚀 Для чего используется ViewModel?

  • Сохранение состояния UI: Самый частый случай — предотвращение потери введённых пользователем данных, состояния списков или выбранных элементов при повороте экрана.
  • Разделение ответственности (по принципам чистой архитектуры): ViewModel отвечает за подготовку данных для UI, в то время как активити/фрагмент отвечает только за их отображение и обработку пользовательского ввода.
  • Управление данными асинхронных операций: В ViewModel удобно запускать и управлять жизненным циклом корутин (Coroutines) или LiveData для загрузки данных из сети или базы данных.
  • Обмен данными между фрагментами: Если несколько фрагментов находятся в одной активити, они могут использовать общий ViewModel (через by activityViewModels()) для обмена информацией.

💻 Пример базовой реализации

Рассмотрим простой пример счетчика, состояние которого сохраняется при повороте экрана.

1. ViewModel (CounterViewModel.kt):

import androidx.lifecycle.ViewModel

class CounterViewModel : ViewModel() {
    // Данные, которые нужно сохранить
    private val _count = MutableLiveData<Int>(0)
    // Публичная неизменяемая версия для наблюдения из UI
    val count: LiveData<Int> = _count

    fun increment() {
        _count.value = (_count.value ?: 0) + 1
    }

    // ViewModel очищает ресурсы здесь
    override fun onCleared() {
        super.onCleared()
        // Освобождение ресурсов (отмена корутин и т.д.)
    }
}

2. Активности (MainActivity.kt), использующая ViewModel:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.lifecycle.Observer

class MainActivity : AppCompatActivity() {
    // Создание или получение существующего экземпляра ViewModel
    private val viewModel: CounterViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val counterTextView = findViewById<TextView>(R.id.counterTextView)
        val incrementButton = findViewById<Button>(R.id.incrementButton)

        // Подписка на изменения LiveData из ViewModel.
        // Текст будет обновляться автоматически при изменении значения count.
        viewModel.count.observe(this, Observer { newCount ->
            counterTextView.text = "Count: $newCount"
        })

        incrementButton.setOnClickListener {
            // Вызов метода ViewModel по действию пользователя.
            // Вся бизнес-логика инкремента находится внутри ViewModel.
            viewModel.increment()
        }
    }
}

🧠 Важные особенности и лучшие практики

  • Не храните ссылки на View (Context, Activity, Fragment): Это может привести к утечке памяти, так как ViewModel переживает конфигурационные изменения, а View — нет. Если нужен Context, используйте AndroidViewModel (которая получает Application контекст).
  • ViewModel — не серебряная пуля: Она не предназначена для замены онкретных сохраняемых состояний (например, введённого текста в EditText), которые система Android восстанавливает сама через onSaveInstanceState(). ViewModel лучше для более тяжёлых данных: списков пользователей, загруженных с сети, сложных состояний UI.
  • Использование с Kotlin Coroutines: В современных приложениях ViewModel часто является scope для запуска корутин через viewModelScope.launch { ... }, которые автоматически отменяются при очистке ViewModel.

Таким образом, ViewModel — это фундаментальный компонент для построения стабильных, тестируемых и устойчивых к изменениям конфигурации Android-приложений в рамках рекомендаций Google (MVVM, Clean Architecture). Она абстрагирует данные UI от их представления, делая код более модульным и простым в поддержке.

Что такое ViewModel в Android? Какие её свойства и для чего она используется? | PrepBro