Как ответить
ViewModel в MVVM — это прослойка между View (Activity/Fragment/Composable) и Model (репозитории, use case'ы). Её задача — хранить состояние UI и бизнес-логику, связанную с отображением, так, чтобы View могла переживать повороты экрана и пересоздания без потери данных. ViewModel не знает о View напрямую — она общается через подписку на LiveData, StateFlow или SharedFlow.
В Android ViewModel живёт в собственном скоупе (ViewModelStoreOwner), который переживает конфигурационные изменения. Когда Activity пересоздаётся, ViewModel остаётся в памяти — это ключевое отличие от простого хранения данных в Activity. View подписывается на стейт из ViewModel и реагирует на изменения, а ViewModel получает действия от View через вызов методов (например, viewModel.onButtonClick()).
Типичная реализация на Kotlin с StateFlow:
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun loadData() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val data = repository.fetchData()
_uiState.value = UiState.Success(data)
} catch (e: Exception) {
_uiState.value = UiState.Error(e.message)
}
}
}
}View подписывается в onCreate через repeatOnLifecycle или observe:
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { state ->
render(state)
}
}
}Важно: ViewModel не должна держать ссылки на View (Activity, Fragment, Context), иначе утечка памяти. Для доступа к Application используйте AndroidViewModel. Для передачи событий (однократных действий типа навигации) — SharedFlow или Channel, а не LiveData, чтобы избежать повторного воспроизведения.
На практике MVVM с ViewModel решает проблему сохранения состояния при повороте, упрощает тестирование (ViewModel тестируется без UI) и отделяет бизнес-логику от фреймворка. Но не стоит пихать всю логику в ViewModel — если она становится слишком большой, выносите в use case'ы или репозитории.