안드로이드 탐구 : ViewModelStore & ViewModelStoreOwner

Skele·2025년 6월 23일
0
post-thumbnail

ViewModelScopeActivityFragment로 지정되면서도 해당 Activity가 파괴되고 재생성되더라도 유지된다. 어떻게 인스턴스가 사라지는데도 ViewModel은 유지될 수 있을까?

ViewModelStore

ViewModelStore

Class to store ViewModels.
Instances of ViewModelStore must 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 the ViewModelStore.
If the owner of a ViewModelStore is destroyed and is not going to be recreated, it should
call [clear] on this ViewModelStore so that The ViewModels stored by it are notified that
they are no longer needed.
Use [ViewModelStoreOwner.getViewModelStore] to retrieve a ViewModelStore for activities and
fragments.

ViewModel을 저장하기 위한 클래스이다.
ViewModelViewModelStore라는 객체에 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()
    }
}

ViewModelStoreOwner

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.

ViewModelActivityFragment가 잠시 파괴되더라도 새로운 인스턴스로 전달되며, ViewModelStoreOwner가 완전히 파괴될 때, clear()를 호출해 Map이 비워지며 ViewModel도 같이 사라진다.

public interface ViewModelStoreOwner {

    /** The owned [ViewModelStore] */
    public val viewModelStore: ViewModelStore
}

ViewModel를 다루다보면 Activity Fragment, NavBackStackEntryViewModel을 소유하며 관리한다는 것을 알 수 있을 것이다.
왜냐하면 ViewModelStoreOwner가 이 ViewModelStore를 가지고 관리하는데, ViewModelStoreOwner를 상속하는 클래스들로 ComponentActivity, Fragment, NavBackStackEntry가 있기 때문이다.

Summary

  • ViewModel은 직접 ActivityFragment에 저장되는 것이 아니라, ViewModelStore라는 별도의 저장소에 보관된다.
  • ViewModelStoreViewModel들을 내부 Map으로 관리하는 클래스로, Configuration Change가 발생해도 이 인스턴스 자체는 시스템에 의해 보존된다. ActivityFragment가 재생성될 때, 새로운 인스턴스는 기존의 ViewModelStore를 다시 참조하게 된다.
  • ViewModelStoreOwner는 이 ViewModelStore를 소유하고 관리하는 역할을 한다. ComponentActivity, Fragment, NavBackStackEntry가 이 인터페이스를 구현하여 ViewModelStore의 생명주기를 관리한다. Configuration Change 시에는 ViewModelStore를 유지하고, 완전히 파괴될 때만 clear()를 호출해 저장된 ViewModel들을 정리한다.
  • 결국 "소유자"인 Activity,Fragment 인스턴스는 바뀌지만, 실제 ViewModel이 저장된 ViewModelStore는 연속성을 유지하기 때문에 ViewModelConfiguration Change에서 살아남을 수 있는 것이다.
profile
Tireless And Restless Debugging In Source : TARDIS

0개의 댓글