ViewModel构造
ViewModel
ViewModel的构造
viewModel = new ViewModelProvider(this).get(UserViewModel.class);
ViewModelProvider的构造
////////////////////
// field ///
//////////////////
private final Factory mFactory;
private final ViewModelStore mViewModelStore;
private static final String DEFAULT_KEY =
"androidx.lifecycle.ViewModelProvider.DefaultKey";
////////////////////
// 构造方法 ///
//////////////////
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
// 如果传入的生命周期绑定对象,实现了HasDefaultViewModelProviderFactory则返回其实现的getDefaultViewModelProviderFactory()方法返回的对象,否则就返回NewInstanceFactory.getInstance()
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
******************************************************
*** Fragment实现了该接口,分析fragment的该实现方法 ***
******************************************************
@NonNull
@Override
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;
}
// 可以看出来SavedStateViewModelFactory继承自ViewModelProvider的一个内部类,并且封装了一个AndroidViewModelFactory
public final class SavedStateViewModelFactory extends ViewModelProvider.KeyedFactory{
////////////////////
// field ///
//////////////////
private final Application mApplication;
private final ViewModelProvider.AndroidViewModelFactory mFactory;
private final Bundle mDefaultArgs;
private final Lifecycle mLifecycle;
private final SavedStateRegistry mSavedStateRegistry;
public SavedStateViewModelFactory(@NonNull Application application,
@NonNull SavedStateRegistryOwner owner,
@Nullable Bundle defaultArgs) {
mSavedStateRegistry = owner.getSavedStateRegistry();
mLifecycle = owner.getLifecycle();
mDefaultArgs = defaultArgs;
mApplication = application;
mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
}
}
public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
this(owner.getViewModelStore(), factory);
}
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
mViewModelStore = store;
}
///////////////////////////////
// 构造ViewMdoel的方法 ///
/////////////////////////////
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
// 拿到viewModel实体类的规范类名
String canonicalName = modelClass.getCanonicalName();
if (canonicalName == null) {
throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
}
return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}
@NonNull
@MainThread
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.
}
}
// fragment的mFactory的是上述中封装的SavedStateViewModelFactory继承自KeyedFactory。KeyedFactory继承自OnRequeryFactory并实现了Factory接口
if (mFactory instanceof KeyedFactory) {
//此处的KeyedFactory是指静态抽象类不是接口
viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
} else {
viewModel = (mFactory).create(modelClass);
}
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
//////////////////////////分析SavedStateViewModelFactory的create方法//////////////////
private static final Class<?>[] ANDROID_VIEWMODEL_SIGNATURE = new Class[]{Application.class,
SavedStateHandle.class};
private static final Class<?>[] VIEWMODEL_SIGNATURE = new Class[]{SavedStateHandle.class};
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
// ViewModelProvider calls correct create that support same modelClass with different keys
// If a developer manually calls this method, there is no "key" in picture, so factory
// simply uses classname internally as as key.
String canonicalName = modelClass.getCanonicalName();
if (canonicalName == null) {
throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
}
return create(canonicalName, modelClass);
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
// 判断modelClass是否属于是AndroidViewModel的子类
boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
Constructor<T> constructor;
if (isAndroidViewModel) {
constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
} else {
//构造方法的参数为有一个SavedStateHandle类参数的构造方法
constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
}
// 如果该类没有只有一个SavedStateHandle参数的构造方法则使用AndroidViewModelFactory的构造方法,如果该类继承自AndroidViewModel则会调用AndroidViewModelFactory带Application参数的构造方法,否则就返回无参构造方法
// doesn't need SavedStateHandle
if (constructor == null) {
return mFactory.create(modelClass);
}
SavedStateHandleController controller = SavedStateHandleController.create(
mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
// 如果该构造函数doesn't need SavedStateHandle则该使用该构造函数构造时传入从controller拿到的SavedStateHandle参数
try {
T viewmodel;
if (isAndroidViewModel) {
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());
}
}
create方法先拿到要构造的套构造的ViewModel类的规范类名,然后利用反射找出构造函数,接着完成ViewModel的构造并返回,要想使用ViewModel带
Applic构造方法该ViewModel必须继承自AndroidViewModel。
////////////////////结束//////////////////////////
我们上边介绍的是ViewModel的构造
ViewModel
为什么Viewmodel可以在手机旋转后导致activity销毁后仍可以恢复其中的数据?
ViewModelStoreOwner是一个接口activity实现,activity保存并持有viewmodelstore,viewmodelstore内部维护了一个hashmap<String,Viewmodel>
当我们使用viewmodelProvider(viewmodelstoreOwner).get(class)的时候会从viewmodelStroe中取出相应的key为viewmodel.classs name + defaValue 的viewmodel。ActivityThread.performDestroyActivity(会调度执行onDestory()方法)会被执行,在ActivityThread.performDestroyActivity中activity会调用retainNonConfigurationInstances()在该方法中会执行onRetainNonConfigurationInstance()在该方法里getLastNonConfigurationInstance()拿到NonConfigurationInstances(该类内部保存了viewModelStore)改值返回到retainNonConfigurationInstances()中并保存在ActivityThread中。下次 Activity 重建时,由 ActivityThread.performLaunchActivity 方法中调用Activity.attach 方法,再将 NonConfigurationInstances 实例传给重建后的 Activity。现在的问题是Viewmodel现在由activity关了,谁来决定他的销毁,原来viewmodel在创建的时候就开始观察activity生命周期,当他被销毁并且配置没有发生改变就会清空内部的数据。