写点什么

Android 架构组件—ViewModel 原理,flutter 瀑布流布局插件

用户头像
Android架构
关注
发布于: 2 小时前

[](


)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 参数。


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


[](


)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。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android架构组件—ViewModel原理,flutter瀑布流布局插件