Android 架构组件—ViewModel 原理,flutter 瀑布流布局插件
[](
)ViewModel 的优势
[](
)与 UI 层低耦合
在 MVVM 模式中,数据和业务逻辑可以集中在 ViewModel 中处理,实现功能时只需要在 ViewModel 中关注数据和业务即可,不需要和 UI 或者控件打交道。
[](
)Fragment 间共享 ViewModel
与其说是共享 ViewModel,不如说是共享数据。在[Android 文档](
)中有提到通过 ViewModel 在 Fragment 中共享数据,使用 ViewModel 共享数据可以免去 Fragment 之前相互回调。
[](
)数据一直保存在内存中
这个优势具体来讲是在系统配置发生变化导致 Activity 重建时,ViewModel 还是会保持在内存中。在一些场景中可以通过这种方式避免重复加载数据。
[](
)ViewModel 工作原理
在分析 ViewModel 的工作原理之前,我们最好带着问题去分析。
ViewModel 如何被创建的,在什么时候被销毁;
ViewModel 的生命周期如何与组件生命周期绑定;
为什么 Activity 重建时 ViewModel 的数据没有丢失;
Fragment 之前如何共享 ViewModel;
[](
)ViewModel 的创建与销毁
[](
)ViewModel 的创建
分析 ViewModel 的创建自然是从 ViewModel 初始化的地方开始。
viewModel = ViewModelProvider(this).get(TestViewModel::class.java)
ViewModel 的初始化很简单,通过 ViewModelProvider 就可以获取到 ViewModel 实例。那么从这里入手开始分析 ViewModel 的创建过程。
第一步是先初始化了一个 ViewModelProvider 对象,所以我们先看下 ViewModelProvider 的构造方法;
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
this(owner.getViewModelStore(), factory);
}
从 ViewModelProvider 的构造方法中可以看到最终是需要两个参数 ViewModelStoreOwner 以及 Factory。这两个参数中 ViewModelStoreOwner 是用来存储 ViewModel 对象的,Factory 是用来创建 ViewModel 对象。这个接下来的分析中也会提到。
第二步是通过 ViewModelProvider 的 get()方法获取 ViewModel 实例。
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key); // 1.是否有缓存 ViewModel 实例缓存
...
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
} else {
viewModel = (mFactory).create(modelClass);
}
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
在 get()方法中可以看到是通过 mFactory 的类型来创建 ViewModel 的。而 Factory 的类型是由 ViewModelStoreOwner 决定的,这是 ViewModelProvider 的构造方法中的逻辑。其中有两种 Factory,一种是 SavedStateViewModelFactory,另一种是 NewInstanceFactory。接下来我们直接看两种方式的区别。
[](
)SavedStateViewModelFactory 创建 ViewModel
public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
Constructor<T> constructor;
...
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;
}
...
}
在代码中可以看到,ViewModel 有分为 AndroidViewModel 跟 ViewModel,它们的区别是 AndroidViewModel 创建时会加入 Application 参数。
[](
)NewInstanceFactory 创建 ViewModel
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//noinspection TryWithIdenticalCatches
try {
return modelClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
NewInstanceFactory 创建过程相对简单,通过 Class 的 newInstance()方法直接创建 ViewModel 实例。
[](
)ViewModel 的销毁
这里还要分开两处说,一个是在 Activity 中的销毁过程,一个是在 Fragment 中销毁过程。
首先我们把目光放到 ViewModel 类来看下 ViewModel 销毁时都做了什么。
protected void onCleared() {}
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 中有 clear()方法和 onCleared()方法。通过跟踪方法的调用可以知道 ViewModel 的销毁过程。最终在 ViewModelStore 类中找到了 clear()方法。
public final void clear() {
for (ViewModel vm : mMap.values()) {
vm.clear();
}
mMap.clear();
}
[](
)Activity 中的销毁
继续跟踪代码可以看到在 ComponentActivity 中:
public ComponentActivity() {
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations()) {
// 销毁 ViewModel
getViewModelStore().clear();
}
}
}
});
}
在 ComponentActivity 的构造方法中,可以看到通过 Lifecycle 在 ON_DESTROY 事件中销毁 ViewModel。
评论