首先看看ViewModel是怎么样实例化
protected open fun <T : ViewModel?> getFragmentScopeViewModel(modelClass: Class<T>): T {
if (!::fragmentProvider.isInitialized) {
fragmentProvider = ViewModelProvider(this)
}
return fragmentProvider.get(modelClass)
}
protected open fun <T : ViewModel?> getActivityScopeViewModel(modelClass: Class<T>): T {
if (!::activityProvider.isInitialized) {
activityProvider = ViewModelProvider(requireActivity())
}
return activityProvider.get(modelClass)
}
我超,原来是通过一个ViewModelProvider去get到的,他妈的这是干什么的呢,为什么要通过ViewModelProvider获取呢
我怎么知道,瞧瞧官方正儿八经的回答吧
ViewModel
:旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存
ViewModelProvider
: ViewModel的辅助程序类,该类负责为界面准备数据。在配置更改期间会自动保留 ViewModel 对象,以便它们存储的数据立即可供下一个 activity 或 fragment 实例使用
好家伙,原来是这对组合,以生命周期的方式耶,看看有什么不同
Activty与ViewModel的生命周期
牛逼,战斗直至Finish
官方说:ViewModel对象存在的时间范围是获取 ViewModel 时传递给 ViewModelProvider 的Lifecycle。ViewModel将一直留在内存中,直到限定其存在时间范围的Lifecycle永久消失:对于activity,是在activity完成时;而对于fragment,是在 fragment分离时
好了,来看看ViewModelProvider是怎样实现构造的
ViewModelProvider()
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
// 尼玛的,偷偷调用另一构造函数
// 1.创建用来存储ViewModel的ViewModelStore, 2. 创建用于实例化新ViewModel的Factory
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
ViewModelStore
这个是接口何许玩意,原来到后面Activity,Fragment等都实现了这个接口,以来获取跟当前生命周期相关的ViewModelStore,看到没有,有图有真相
看看
ComponentActivity.getViewModelStore()
:
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.");
}
// 叉,这里照我猜想肯定是实现ViewModelStore的单例
ensureViewModelStore();
// 返回与此Activity关联的ViewModelStore
return mViewModelStore;
}
```
void ensureViewModelStore() {
if (mViewModelStore == null) {
// 检索先前由onRetainNonConfigurationInstance()返回的配置变更后的缓存配置
NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();
// 如果缓存配置不为空,则取缓存配置的viewModelStore
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
// 否则自己实例一个
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}
嘿嘿,存储ViewModel的ViewModelStore,牛逼啊,用一个HashMap来缓存看到有木有:
public class ViewModelStore {
private final HashMap<String, ViewModel> mMap = new HashMap<>();
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = mMap.put(key, viewModel);
if (oldViewModel != null) oldViewModel.onCleared();
}
final ViewModel get(String key) {
return mMap.get(key);
}
Set<String> keys() {
return new HashSet<>(mMap.keySet());
}
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
}
ViewModelProviderFactory
同样的后面Activity,Fragment等也实现了HasDefaultViewModelProviderFactory接口,实现自己创建ViewModel的ViewModelProviderFactory, 来看图
再来看看
ComponentActivity.getViewModelStore()
:
public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
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 (mDefaultFactory == null) {
mDefaultFactory = new SavedStateViewModelFactory(
getApplication(),
this,
getIntent() != null ? getIntent().getExtras() : null);
}
return mDefaultFactory;
}
有点东西,这样就实例SavedStateViewModelFactory
了,看看具体怎么get()
霍
// 第一步:小get
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
String canonicalName = modelClass.getCanonicalName();
// 好家伙,看到没有,如果这里判断是局部类或者匿名类,就直接给crash了,谷歌就是牛逼
if (canonicalName == null) {
throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
}
// 嘿,继续get下去
return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}
// 第二步:大get
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;
}
// 然后如果为null,则通过具体工厂类去实例化ViewModel
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) mFactory).create(key, modelClass);
} else {
viewModel = mFactory.create(modelClass);
}
// 嘿嘿,放进缓存
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
// ViewModel的实例化
public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
Constructor<T> constructor;
// 通过反射,去找到当前ViewModel的构造函数
if (isAndroidViewModel && mApplication != null) {
constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
} else {
constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
}
if (constructor == null) {
return mFactory.create(modelClass);
}
SavedStateHandleController controller = SavedStateHandleController.create(
mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
// 嘿嘿,调用构造函数,实例化
try {
T viewmodel;
if (isAndroidViewModel && mApplication != null) {
viewmodel = constructor.newInstance(mApplication, controller.getHandle());
} else {
viewmodel = constructor.newInstance(controller.getHandle());
}
viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
return viewmodel;
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to access " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("A " + modelClass + " cannot be instantiated.", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("An exception happened in constructor of "
+ modelClass, e.getCause());
}
}
ViewModel的架构作用
向官方敬礼,懂不懂这张图的含金量,懂不懂MMVM