6. ViewModelStore 와 ViewModelStoreOwner
① ViewModelStore 은 ViewModel 객체를 저장하기 위한 클래스입니다. 내부에 ViewModel 을 저장하기 위해 HashMap<String, ViewModel> 을 가지고 있으며, put(ViewModelStore 에 ViewModel 저장), get(ViewModelStore 에 저장된 ViewModel 반환), clear(ViewModelStore 에 저장된 ViewModel 객체 정리) 메서드를 제공합니다.
② ViewModelStore 객체는 ViewModelStoreOwner 인터페이스 구현 객체에서 관리합니다. Activity(ComponentActivity class) 또는 Fragment(Fragment class) 는 ViewModelStoreOwner 인터페이스를 구현한 ViewModelStoreOwner 입니다.
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
...
LifecycleOwner,
ViewModelStoreOwner,
... {
...
private ViewModelStore mViewModelStore;
...
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
ensureViewModelStore();
return mViewModelStore;
}
}
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner,
...{
//Fragment 는 FragmentManagerViewModel class 가 ViewModelStore 를 가지고 있습니다.
@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (mFragmentManager == null) {
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
if (getMinimumMaxLifecycleState() == Lifecycle.State.INITIALIZED.ordinal()) {
throw new IllegalStateException("Calling getViewModelStore() before a Fragment "
+ "reaches onCreate() when using setMaxLifecycle(INITIALIZED) is not "
+ "supported");
}
return mFragmentManager.getViewModelStore(this);
}
}
③ ViewModelProvider 생성자에서 ViewModelStoreOwner 객체를 받아서 내부 필드로 저장하고 있다가 get 메서드를 통해 ViewModel 을 요청하면 필드에 저장된 ViewModelStoreOwner 객체에서 관리중인 ViewModelStore 에 요청된 ViewModel 객체가 있는지 확인하고 없다면 생성하여 ViewModelStore 에 저장한 후 반환해줍니다.
④ ViewModelProvider 에 전달하는 ViewModelStoreOwner 객체의 종류에 따라(예: MainActivity, SignUpFragment 등등) 생성되는 ViewModel 의 스코프가 결정됩니다. 만약 MainActivity 에 BottomNavigationView 를 사용하여 AFragment, BFragment, CFragment 를 연결하고 각 Fragment 에서 ViewModel 를 생성할 때 ViewModelStoreOwner 로 MainActivity 를 제공했다면 MainActivity 가 관리하는 ViewModelStore 에 ViewModel 이 저장되기 때문에 각 Fragment 들이 파괴되더라도 MainActivity 만 파괴되지 않는다면(Device Configuration 에 의한 파괴를 제외한) ViewModelStore 에서 보관중인 ViewModel 은 파괴되지 않습니다.