ViewModel

https://developer.android.com/topic/libraries/architecture/viewmodel
https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-factories
https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-apis
https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-savedstate
https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-cheatsheet

ViewModel

Хранит состояние бизнес-логики экрана. Предоставляет состояние UI и инкапсулирует соответствующую бизнес-логику. Основное преимущество заключается в том что он кэширует состояние и сохраняет его при изменениях конфигурации. Это означает что вашему UI не нужно повторно получать данные при переходе между экранами или после изменений конфигурации, например при повороте экрана.

• при переходе на следующий экран ViewModel должна жить.

• при переходе на предыдущий экран ViewModel должна умереть.

AndroidViewModel

ViewModel с контекстом приложения. Подклассы должны иметь конструктор, который принимает Application в качестве единственного параметра.

Assisted

@HiltViewModel(assistedFactory = MyViewModel.Factory::class)
class MyViewModel @AssistedInject constructor(
		@Assisted val userId: Int,
		savedStateHandle: SavedStateHandle
): ViewModel() {
		
		@AssistedFactory
		interface Factory {
				fun create(userId: Int): MyViewModel
		}
}

@Composable
fun MyScreen(
		userId: Int,
		viewModel: MyViewModel = hiltViewModel(
				creationCallback = { factory: MyViewModel.Factory -> factory.create(userId) }
		)
) {}

ViewModelStore

Класс который хранит экземпляры ViewModel. Внутри лежит mutableMapOf<String, ViewModel> где ключ - идентификатор модели. Каждая Activity, Fragment, View или Composable имеют собственный ViewModelStore который живет в течение lifecycle элемента. Класс ViewModelStore в andoridx-репозитории.

ViewModelStoreOwner

Интерфейс который обеспечивает доступ к ViewModelStore.

ViewModelProvider

Класс отвечает за создание и получение ViewModel. Есть методы get и create.

ViewModelProvider.Factory

Интерфейс который даёт нам метод для создания ViewModel. По умолчанию используется DefaultViewModelProviderFactory если мы не сделаем собственную реализацию. Кастомные Factory позволяют создавать ViewModel с параметрами конструктора что дает дополнительную гибкость.

Lifecycle

Когда мы запрашиваем ViewModel - ViewModelProvider проверяет существует ли такая модель. Если найдена - возвращается экземпляр. Если не найдена - ViewModelProvider.Factory используется для создания новой ViewModel и она потом сохраняется в ViewModelStore. Созданная ViewModel жива пока жив экран. Когда экран уничтожается - ViewModelStore очищается и все хранящиеся в нем ViewModel удаляются. Для каждой ViewModel вызывается onCleared .

Как сохраняется ViewModel?

ViewModel не уничтожается при смене конфигурации. Объекты ViewModel сохраняются в специальном хранилище - ViewModelStore. Вновь созданный экран может получить доступ к существующему экземпляру ViewModel.

SavedStateHandle

Key-value мапа. Передается в конструктор вьюмодели. Позволяет записывать и извлекать объекты из сохраненного состояния.

@HiltViewModel
class MyViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle
): ViewModel() {
		private val id: Int? = savedStateHandle.get<Int>("id")
		private val idStateFlow: StateFlow<Int> = savedStateHandle.getStateFlow("id", 0)
		
		init {
				savedStateHandle["id"] = 1
        savedStateHandle.remove<Int>("id")
    }
}

ViewModel. Вопросы на собесе
  1. Что такое ViewModel и какова его роль в архитектуре Android?
  1. Как ViewModel взаимодействует с жизненным циклом Activity или Fragment?
  1. Что такое SavedStateHandle и как его использовать в ViewModel?
  1. Как разделять ViewModel между несколькими Fragment в одной Activity?
  1. Как ViewModel переживает пересоздание Activity?

    ViewModel сохраняется в ViewModelStore, и новая Activity получает доступ к той же ViewModel, избегая ее пересоздания.