
ViewModel의 Scope는 Activity나 Fragment로 지정되면서도 해당 Activity가 파괴되고 재생성되더라도 유지된다. 어떻게 인스턴스가 사라지는데도 ViewModel은 유지될 수 있을까?
ViewModelStore
Class to store
ViewModels.
Instances ofViewModelStoremust be retained through configuration changes. If the owner of a
ViewModelStore, typically a [ViewModelStoreOwner], is destroyed and recreated due to a
configuration change, the new owner must have the old instance of theViewModelStore.
If the owner of aViewModelStoreis destroyed and is not going to be recreated, it should
call [clear] on thisViewModelStoreso that TheViewModels stored by it are notified that
they are no longer needed.
Use [ViewModelStoreOwner.getViewModelStore] to retrieve aViewModelStorefor activities and
fragments.
ViewModel을 저장하기 위한 클래스이다.
ViewModel은 ViewModelStore라는 객체에 Map으로 저장이 되어 Configuration Change에 걸쳐 이 인스턴스가 유지된다.
public open class ViewModelStore {
private val map = mutableMapOf<String, ViewModel>()
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun put(key: String, viewModel: ViewModel) {
val oldViewModel = map.put(key, viewModel)
oldViewModel?.clear()
}
/** Returns the `ViewModel` mapped to the given `key` or null if none exists. */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public operator fun get(key: String): ViewModel? {
return map[key]
}
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun keys(): Set<String> {
return HashSet(map.keys)
}
/** Clears internal storage and notifies `ViewModel`s that they are no longer used. */
public fun clear() {
for (vm in map.values) {
vm.clear()
}
map.clear()
}
}
A scope that owns [ViewModelStore].
A responsibility of an implementation of this interface is to retain owned ViewModelStore during
the configuration changes and call [ViewModelStore.clear], when this scope is going to be
destroyed.
ViewModel은 Activity나 Fragment가 잠시 파괴되더라도 새로운 인스턴스로 전달되며, ViewModelStoreOwner가 완전히 파괴될 때, clear()를 호출해 Map이 비워지며 ViewModel도 같이 사라진다.
public interface ViewModelStoreOwner {
/** The owned [ViewModelStore] */
public val viewModelStore: ViewModelStore
}
ViewModel를 다루다보면 Activity Fragment, NavBackStackEntry가 ViewModel을 소유하며 관리한다는 것을 알 수 있을 것이다.
왜냐하면 ViewModelStoreOwner가 이 ViewModelStore를 가지고 관리하는데, ViewModelStoreOwner를 상속하는 클래스들로 ComponentActivity, Fragment, NavBackStackEntry가 있기 때문이다.
ViewModel은 직접 Activity나 Fragment에 저장되는 것이 아니라, ViewModelStore라는 별도의 저장소에 보관된다.ViewModelStore는 ViewModel들을 내부 Map으로 관리하는 클래스로, Configuration Change가 발생해도 이 인스턴스 자체는 시스템에 의해 보존된다. Activity나 Fragment가 재생성될 때, 새로운 인스턴스는 기존의 ViewModelStore를 다시 참조하게 된다.ViewModelStoreOwner는 이 ViewModelStore를 소유하고 관리하는 역할을 한다. ComponentActivity, Fragment, NavBackStackEntry가 이 인터페이스를 구현하여 ViewModelStore의 생명주기를 관리한다. Configuration Change 시에는 ViewModelStore를 유지하고, 완전히 파괴될 때만 clear()를 호출해 저장된 ViewModel들을 정리한다.Activity,Fragment 인스턴스는 바뀌지만, 실제 ViewModel이 저장된 ViewModelStore는 연속성을 유지하기 때문에 ViewModel이 Configuration Change에서 살아남을 수 있는 것이다.