基本上,为了在Activity 中检索ViewModel,应该调用ViewModelProviders.of(this).get(SomeViewModel.class)。现在,如果我们查看of,它如下所示:
public static ViewModelProvider of(@NonNull FragmentActivity activity,
@Nullable Factory factory) {
Application application = checkApplication(activity);
if (factory == null) {
factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(activity.getViewModelStore(), factory);
}
所以,重要的部分是这个方法 - activity.getViewModelStore(),因为它为您的所有 ViewModel 对象返回一个包装器对象(HashMap 持有者),如果它可以在配置更改中幸存下来,那么您的所有 ViewModel对象:
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.");
}
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
return mViewModelStore;
}
mViewModelStore 将从 NonConfigurationInstances 恢复或从头开始创建。几乎,NonConfigurationInstances 是在配置更改后仍然存在的对象,因此用于存储ViewModelStore。这就是为什么在旋转后返回相同的 ViewModelStore 对象 - 它存储在独立于配置更改的 NonConfigurationInstances 中:
如果您查看onRetainNonConfigurationInstance(),您实际上会发现您的ViewModelStore 保存在那里:
public final Object onRetainNonConfigurationInstance() {
...
NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;
}
此外,仅当由于非配置更改原因调用 onDestroy 时才会清除它:
...
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
...
类似的技巧用于将ViewModel 存储为Fragment。