ViewModel源码阅读条记

源码 2024-9-2 08:39:40 33 0 来自 中国
MVVM模式实现了数据和页面的分离。ViewModel的生命周期必要跟随引用他的activity大概fragment。接下来我们就来看看,ViewModel是怎样实现生命周期的陪同的。
先从ViewModel的创建开始看
XXXViewModel viewModel = new  ViewModelProvider(fragment).get(XXXViewModel.class)kotlin扩展函数实现的方式终极也是调用ViewModelProvider的方法实现的,具体细节可以看上篇文章先容,这里不赘述了
先看下ViewModelProvider的构造方法
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {  this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory          ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()          : NewInstanceFactory.getInstance());  }构造方法必要传入一个ViewModelStoreOwner,在androidx包中的Fragment和ComponentActivity都实现了这个接口。这个稍后再看
继续看上面的代码,该构造方法调用了另一个构造方法
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {      mFactory = factory;      mViewModelStore = store;  }mViewModelStore这个变量来自于ViewModelStoreOwner,接下来以Fragment为例,来看看
public ViewModelStore getViewModelStore() {      if (mFragmentManager == null) {          throw new IllegalStateException("Can't access ViewModels from detached fragment");      }      return mFragmentManager.getViewModelStore(this);  }这里可以看出,Fragment的ViewModelStore是生存在当前实例下。先记住这个结论,待会还用得着。
接下来看factory参数,fragment也是HasDefaultViewModelProviderFactory的实现类,因此获取factory的实例方法为
public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {      if (mFragmentManager == null) {          throw new IllegalStateException("Can't access ViewModels from detached fragment");      }      if (mDefaultFactory == null) {          mDefaultFactory = new SavedStateViewModelFactory(              requireActivity().getApplication(),              this,              getArguments());      }      return mDefaultFactory;  }这里的factory也是fragment中生存的实例
回到ViewModelProvider的get方法
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {      String canonicalName = modelClass.getCanonicalName();      if (canonicalName == null) {          throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");      }      return get(DEFAULT_KEY + ":" + canonicalName, modelClass);  }终极调用的是
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {      ViewModel viewModel = mViewModelStore.get(key);    if (modelClass.isInstance(viewModel)) {          if (mFactory instanceof OnRequeryFactory) {              ((OnRequeryFactory) mFactory).onRequery(viewModel);          }          return (T) viewModel;      } else {          //noinspection StatementWithEmptyBody          if (viewModel != null) {              // TODO: log a warning.          }      }      if (mFactory instanceof KeyedFactory) {          viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);      } else {          viewModel = (mFactory).create(modelClass);      }      mViewModelStore.put(key, viewModel);      return (T) viewModel;  }这里获取缓存的viewmodel的方法 mViewModelStore.get(key)。这里的mViewModelStore就是fragment中存储的。
讲到这里,实在已经清楚了生命周期的绑定过成了。
在ViewModelProvider获取ViewModel的时间,实际上是从fragment中拿到的,如果fragment中没有的话,就创建一个,将其生存在fragment中。因此,只要拿到的fragment实例为同一个,无论新创建多少个ViewModelProvider的实例,终极获取的ViewModel都是同一个。而由于ViewModel的实例实际上是生存在fragment中,因此,viewmodel也会随fragment的烧毁而烧毁。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 16:50, Processed in 0.143212 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表