目录
一、ViewModel的出生
二、ViewModel的结束
三、总结:
我们通过ViewModel的生命周期来作为主线,讲解ViewModel、ViewModelProvider、ComponentActivity三者的关系。
创建ViewModel,通过调用ViewModelProvider的get方法。
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
//ViewModelProvider.class
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
mViewModelStore = store;
}
public ViewModelStore getViewModelStore() {
...
ensureViewModelStore();
return mViewModelStore;
}
void ensureViewModelStore() {
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
}
获取owner的ViewModelStore(AppCompatActivity 兼容 -> FragmentActiity -> ComponentActivity 组件 ComponentActivty实现了ViewModelStoreOwner和LifecycleOwner接口)
ViewModelStore内部有一个HashMap用来存储ViewModel
所以ViewModelStore里的mViewModelStore即是Activity,ViewModelProvider持有mViewModelStore的引用,ViewModelProvider内部持有mViewModelStore引用
//ViewModelProvider.class
public T get(@NonNull Class modelClass) {
...
return get(DEFAULT_KEY + ":" + modelClass.getCanonicalName(), modelClass);
}
public T get(@NonNull String key, @NonNull Class 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;
}
public T create(@NonNull Class modelClass) {
return modelClass.newInstance();
...
}
get方法会创建ViewModel对象,使用Factory工厂来创建 , 工厂通过反射来创建ViewModel。
而由于我们是使用ViewModelProvider(ViewModelStoreOwner))来创建的ViewModelProvider,所以这里使用的ViewModelProvider.Factory其实是ComponentActivity,因为ComponentActivity实现了HasDefaultViewModelProviderFactory接口。
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
...
HasDefaultViewModelProviderFactory{
public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
...
mDefaultFactory = new SavedStateViewModelFactory(
getApplication(),
this,
getIntent() != null ? getIntent().getExtras() : null);
return mDefaultFactory;
}
}
到此,我们创建的ViewModel实际保存在了mViewModelStore的HashMap里,而mViewModelStore是属于Activity的成员变量。
开始:ViewModel的创建上面已经讲的很多了,生命的开始是从我们创建ViewModel开始
结束:而生命的结束就不是由我们自己控制的了,因为我们的ViewModel是存储在Activity的ViewModelStore里,所以生命的结束也是由Activity来处理的。
public ComponentActivity() {
Lifecycle lifecycle = getLifecycle();
...
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
...
getViewModelStore().clear();
}
}
});
...
}
在创建ComponentActivity的时候,我们注册了Activity的Lifecycle监听,当Activity.onDestory的时候会自动清空所有的ViewModel,并且会给ViewModel一个onCleared回调,告诉它已经没人引用它了。并对
ViewModel里的mBagOfTags挨个调用close方法
//ViewModel.class
protected void onCleared() {
}
@MainThread
final void clear() {
mCleared = true;
if (mBagOfTags != null) {
synchronized (mBagOfTags) {
for (Object value : mBagOfTags.values()) {
// see comment for the similar call in setTagIfAbsent
closeWithRuntimeException(value);
}
}
}
onCleared();
}
综上所述,ViewModel是有生命周期的,生命的结束由Activity控制
1、ViewModelProvider其实只是一个中介:
ViewModel的创建,工厂ViewModelProvider.Factory实际是由ComponentActivity持有。
ViewModel的存储,ViewModelStore来负责并且由ComponentActivity持有。
ViewModel的销毁,还是由ComponentActivity来负责。
2、ViewModel就是MVVM中的核心VM,由ComponentActivity来负责生命周期和存储。
3、ComponentActivity就是ViewModel的全权大管家。
4、MVVM中的view层是持有viewmodel层引用的。