ViewModel 是 Jetpack 中的一个组件,它以注重生命周期的方式管理界面的相关数据。 ViewModel的优势是数据持久化,即使手机在横竖屏切换时数据依然存在。
ViewModel的使用
val mViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
ViewModel的创建过程
当执行ViewModelProvider(this).get(UserViewModel::class.java)代码时,会从ViewModelStore中通过类名+ViewModel实例作为key取出ViewModel,如果没有这会创建一个ViewModel出来,然后再存到ViewModelStore中。
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
// 会从ViewModelStore中的HashMap中取出ViewModel
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;
}
接着再看ViewModelProvider的构造方法
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
因为ComponentActivity实现了HasDefaultViewModelProviderFactory接口,所以会执行ComponentActivity中的getDefaultViewModelProviderFactory()方法
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中的create方法
// 通过反射去创建ViewModel实例
public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
Constructor<T> constructor;
if (isAndroidViewModel) {
constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
} else {
constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
}
// doesn't need SavedStateHandle
if (constructor == null) {
return mFactory.create(modelClass);
}
SavedStateHandleController controller = SavedStateHandleController.create(
mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
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);
}
}
数据的存储和恢复
在ComponentActivity类中通过Bundle进行数据的存储和恢复,Bundle作为数据存储,已经和当前Activity实例没有任何关系了。
protected void onCreate(@Nullable Bundle savedInstanceState) {
// Restore the Saved State first so that it is available to
// OnContextAvailableListener instances
mSavedStateRegistryController.performRestore(savedInstanceState);
//........
}
protected void onSaveInstanceState(@NonNull Bundle outState) {
//..........
mSavedStateRegistryController.performSave(outState);
}
生命周期管理
在ComponentActivity的构造方法中有这样一段代码,通过Lifecycle对生命周期进行监听。
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();
}
}
}
});
当isChangingConfigurations()方法返回false时说明屏幕状态没有发生改变,此时会执行ViewModelStore的clear()方法,在clear方法中会循环遍历HashMap中保存的ViewModel对象,调用ViewModel对象的onCleared()方法,在这个方法中执行具体的对象销毁操作。
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}