首页
学习
活动
专区
圈层
工具
发布
30 篇文章
1
android横竖屏切换activity生命周期变化
2
Android:Service生命周期最全面解析
3
Android 面试官:简述一下 View 的绘制流程,这个都答不出来就别想拿Offer了
4
一文解决Android View滑动冲突
5
Android Handler机制11之Handler机制总结
6
android View层的绘制流程
7
深入理解 Android 消息机制原理
8
Android 7.0 中 Launcher 启动 Activity 过程
9
「细品源码」 Android 系统的血液:Handler
10
Android ListView 与 RecyclerView 对比浅析:缓存机制
11
深入理解Android插件化技术
12
Android组件化框架项目详解
13
《Android插件化技术——原理篇》
14
Android面试遇坎,我精选了这些题目与答案,你离大厂还有多远测试一下就知道!
15
史上最全的Android面试题集锦
16
Activity三问—猫眼真题
17
Android 面试黑洞——当我按下 Home 键再切回来,会发生什么?
18
笔记——JVM、DVM(dalvik)和ART之间的区别(二十)
19
ClassLoader解析(二):Android中的ClassLoader
20
Android类加载之PathClassLoader和DexClassLoader
21
用代码手把手教你使用MVVM
22
从构建工具看 Android APK 编译打包流程
23
《Android面试题思考与解答》2021年3月刊
24
《Android面试题思考与解答》2021年1月刊
25
Android MVVM模式入门
26
ViewModel三问—阿里真题
27
ANR 原理与实战技巧
28
你真的会用Retrofit2吗?Retrofit2完全教程
29
Android 进阶11:进程通信之 ContentProvider 内容提供者
30
Android:关于ContentProvider的知识都在这里了!

ViewModel三问—阿里真题

上期我们说过了MVVM架构,那么接下来我们就继续说说里面的相关组件,今天轮到ViewModel :

  • ViewModel 是什么?
  • ViewModel 为什么被设计出来,解决了什么问题?
  • 说说ViewModel原理。

ViewModel 是什么,说说你所理解的ViewModel?

如果看过我上一篇文章的小伙伴应该都有所了解,ViewModel是MVVM架构的一个层级,用来联系View和model之间的关系。而我们今天要说的就是官方出的一个框架——ViewModel。

“ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据 ”

官方是这么介绍的,这里面有两个信息:

  • 注重生命周期的方式。由于ViewModel的生命周期是作用于整个Activity的,所以就节省了一些关于状态维护的工作,最明显的就是对于屏幕旋转这种情况,以前对数据进行保存读取,而ViewModel则不需要,他可以自动保留数据。

其次,由于ViewModel在生命周期内会保持局部单例,所以可以更方便Activity的多个Fragment之间通信,因为他们能获取到同一个ViewModel实例,也就是数据状态可以共享了。

  • 存储和管理界面相关的数据。

ViewModel层的根本职责,就是负责维护界面上UI的状态,其实就是维护对应的数据,因为数据会最终体现到UI界面上。所以ViewModel层其实就是对界面相关的数据进行管理,存储等操作。

ViewModel 为什么被设计出来,解决了什么问题?

  • ViewModel组件被设计出来之前,MVVM又是怎么实现ViewModel这一层级的呢?

其实就是自己编写类,然后通过接口,内部依赖实现View和数据的双向绑定。所以Google出这个ViewModel组件,无非就是为了规范MVVM架构的实现,并尽量让ViewModel这一层级只触及到业务代码,不去关心VIew层级的引用等。然后配合其他的组件,包括livedata,databindingrang等让MVVM架构更加完善,规范,健硕。

  • 解决了什么问题呢?

其实上面已经说过一些了,比如:

1)不会因为屏幕旋转而销毁,减少了维护状态的工作 2)由于在作用域内单一实例的特性,使得多个fragment之间可以方便通信,并且维护同一个数据状态。3)完善了MVVM架构,使得解耦更加纯粹。

说说ViewModel原理。

  • 首先说说是怎么保存生命周期

ViewModel2.0之前呢,其实原理是在Activity上add一个HolderFragment,然后设置setRetainInstance(true)方法就能让这个Fragment在Activity重建时存活下来,也就保证了ViewModel的状态不会随Activity的状态所改变。

2.0之后,其实是用到了Activity的onRetainNonConfigurationInstance()getLastNonConfigurationInstance()这两个方法,相当于在横竖屏切的时候会保存ViewModel的实例,然后恢复,所以也就保证了ViewModel的数据。

  • 再说说怎么保证作用域内唯一实例

首先,ViewModel的实例是通过反射获取的,反射的时候带上application的上下文,这样就保证了不会持有Activity或者Fragment等View的引用。然后实例创建出来会保存到一个ViewModelStore容器里面,其实也就是一个集合类,这个ViewModelStore 类其实就是保存在界面上的那个实例,而我们的ViewModel就是里面的一个集合类的子元素。

所以我们每次获取的时候,首先看看这个集合里面有无我们的ViewModel,如果没有就去实例化,如果有就直接拿到实例使用,这样就保证了唯一实例。最后在界面销毁的时候,会去执行ViewModelStore的clear方法,去清除集合里面的ViewModel数据。一小段代码说明下:

代码语言:javascript
代码运行次数:0
复制
public <T extends ViewModel> T get(Class<T> modelClass) {
      // 先从ViewModelStore容器中去找是否存在ViewModel的实例
      ViewModel viewModel = mViewModelStore.get(key);
     
      // 若ViewModel已经存在,就直接返回
      if (modelClass.isInstance(viewModel)) {
            return (T) viewModel;
      }
       
      // 若不存在,再通过反射的方式实例化ViewModel,并存储进ViewModelStore
      viewModel = modelClass.getConstructor(Application.class).newInstance(mApplication);
      mViewModelStore.put(key, viewModel);
      return (T) viewModel;
 }


public class ViewModelStore {
    private final HashMap<String, ViewModel> mMap = new HashMap<>();

     public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.onCleared();
        }
        mMap.clear();
    }
}



 @Override
protected void onDestroy() {
    super.onDestroy();

   if (mViewModelStore != null && !isChangingConfigurations()) {
        mViewModelStore.clear();
    }

}

参考

https://juejin.im/post/6844903729414537223

下一篇
举报
领券