프래그먼트가 ViewModelStore를 가져오는 과정

홍성덕·2024년 8월 16일

Android ViewModel

목록 보기
3/4
private val viewModel = ViewModelProvider(this@SearchFragment).get(SearchViewModel::class.java)

이렇게 프래그먼트에 선언된 ViewModel 생성 코드로부터, 프래그먼트가 ViewModelStore를 get하는 과정을 알아보았다.

// ViewModelProvider.kt
    public constructor(
        owner: ViewModelStoreOwner
    ) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))

ViewModelProvider 인스턴스를 생성할 때 위의 생성자가 사용되었다. 여기서 owner.viewModelStore의 implementation 된 곳 중 Fragment.java에 구현된 곳으로 따라가보았다.

// Fragment.java
    @NonNull
    @Override
    public ViewModelStore getViewModelStore() {
    	// ...
        return mFragmentManager.getViewModelStore(this);
    }

Fragment에서 getViewModelStore() 메서드를 통해서 ViewModelStore를 가져오는데 이 메서드는 FragmentManager의 getViewModelStore() 메서드와 연결된다.

// FragmentManager.java
    @NonNull
    ViewModelStore getViewModelStore(@NonNull Fragment f) {
        return mNonConfig.getViewModelStore(f);
    }

여기서 mNonConfig.getViewModelStore(f);가 리턴되는데 mNonConfig는

	private FragmentManagerViewModel mNonConfig;

같은 파일 내에 선언되어 있는 FragmentManagerViewModel 타입의 필드이다. 그러면 mNonConfig.getViewModelStore(f);를 따라가보자.

// FragmentManagerViewModel.java
final class FragmentManagerViewModel extends ViewModel {
    // ...
    
    private final HashMap<String, ViewModelStore> mViewModelStores = new HashMap<>();
    
    // ...
    
    @NonNull
    ViewModelStore getViewModelStore(@NonNull Fragment f) {
        ViewModelStore viewModelStore = mViewModelStores.get(f.mWho);
        if (viewModelStore == null) {
            viewModelStore = new ViewModelStore();
            mViewModelStores.put(f.mWho, viewModelStore);
        }
        return viewModelStore;
    }

FragmentManagerViewModel이 대체 어떤 클래스인지 맨처음에는 파악이 잘 안되었지만, ViewModel을 상속한 클래스인 것을 보고 굉장히 쉽게 느껴졌다. 우리가 액티비티나 프래그먼트를 만들면 그에 대한 ViewModel 클래스를 만들듯이, 이것도 FragmentManager 클래스에 대한 ViewModel 클래스일 뿐이다.

먼저 FragmentManagerViewModel에서는 ViewModelStore들을 HashMap<String, ViewModelStore> 타입으로 mViewModelStores에 저장하고 있다. 그리고 getViewModelStore() 메서드를 보면 프래그먼트의 개별 UUID인 f.mWho를 통해 해당 프래그먼트의 ViewModelStore를 get하고 있는 것을 알 수 있다.

결론은 프래그먼트는 FragmentManager를 통해서 ViewModelStore를 가져온다는 것을 알 수 있었다.


참고자료

profile
안드로이드 주니어 개발자

0개의 댓글