IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Jetpack架构组件之ViewModel原理篇 -> 正文阅读

[移动开发]Android Jetpack架构组件之ViewModel原理篇

上一篇文章讲了viewmodel的简单使用

Android Jetpack架构组件之ViewModel使用篇

一、ViewModel

ViewModel是Jetpack AAC的重要组件,同时也有一个同名抽象类。 ViewModel,意为 视图模型,即为界面准备数据的模型。简单理解就是,ViewModel为UI层提供数据。独立的看ViewModel没有什么实际意义,更像是数据容器,结合LiveData使用更容易理解。

二、ViewModel的好处

1、Activity配置更改重建时(比如屏幕旋转)保留数据;

2、UI组件(Activity与Fragment、Fragment与Fragment)间实现数据共享。

????????对于第一条不用VM的情况下只能通过onSaveInstanceState保存数据,当activity重建后再通过onCreateonRestoreInstanceState方法的bundle中取出,但如果数据量较大,数据的序列化和反序列化将产生一定的性能开销。

????????对于第二条如果不用VM,各个UI组件都要持有共享数据的引用,这会带来两个麻烦,第一,如果新增了共享数据,各个UI组件需要再次声明并初始化新增的共享数据;第二,某个UI组件对共享数据修改,无法直接通知其他UI组件,需手动实现观察者模式。而VM结合LiveData就可以很轻松的实现这一点。

LiveData作为数据变化的驱动器,VM借助它可以写出十分简洁的MVVM代码。

????????接下来我们来看一下VM到底是如何实现上述需求的,而事实上核心可以转化为下面两个问题。

三、ViewModel的原理(以? “翻转屏幕”? 更改屏幕配置为例讲解)

? ? ? ? 当屏幕发生翻转时,Activity的onRetainCustomNonConfigurationInstance()方法会被调用,另一个getLastNonConfigurationInstance也会被执行,上面这个方法会有机会调到下面这个get的方法。

?运行验证:

?

?系统调用到这两个API,ViewModel就是利用这两个API来完成数据的保存和恢复的。

从代码使用来寻找原理:

ViewModelProviders.of(this).get(WeatherViewModel.class);

1、先看of方法,进去发现会走到

new ViewModelProvider(activity.getViewModelStore(), (Factory)factory)

new了一个ViewModelProvider;这里发现第一个参数为获取ViewModelStore,接着看从哪获取的

?发现是在ComponentActivity上的;接着看这个ViewModelStore是什么东西

?当上面的getViewModelStore第一次执行的时候mViewModelStore == null,就回去NonConfigurationInstances这个对象上找viewmodelStore(NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();),接着进去getLastNonConfigurationInstance这个方法看看:

?第一次进来这个mLastNonConfigurationInstances变量也是为空,所以这个方法第一次返回null,

?

?所以第一次调用ViewModelProviders.of方法的时候,实际就是去初始化一个ViewModelStore,这就完成了第一步初始化一个存储viewmodel的集合ViewModelStore。

2、接着看使用时候的.get(WeatherViewModel.class),点进去看

??会走:return this.get("androidx.lifecycle.ViewModelProvider.DefaultKey:" + canonicalName, modelClass);这里用一个字符串拼接我们写的ViewModel的类名作为key,viewmodel实例作为value存储起来。(默认创建viewmodel实例的factory利用的反射的方式)

?

?以上的1,2两步就是第一次使用viewmodel的时候of负责创建viewmodelStore,get负责创建viewmodel实例并存到viewmodelStore中。那么这个和屏幕的翻转配置发生变更有什么关联呢?

?3、继续回到上面说的两个API中:onRetainCustomNonConfigurationInstance,getLastNonConfigurationInstance

当竖屏切到横屏时,先走onRetainCustomNonConfigurationInstance保存配置的方法,跟进去看

注意这里的这个nci类是 CompoentActivity的静态内部类,等下和下面的这个nc不一样的,下面的这个nc是Activity的静态内部类。但是这个onRetainNonConfigurationInstance方法是被Activity的retainNonConfigurationInstances调用

?

?好了,到这里为止,就是我们翻转屏幕改变配置的时候走的这个方法onRetainCustomNonConfigurationInstance完成的一些工作。

我们知道当屏幕翻转的时候是会重新走activity的生命周期的,所有的变量也会没值了,就又会走到这个方法的viewmodel的创建过程

?这个时候会走of的activity的getViewModelStore这个方法

?因为:下面这两个都是Activity.java 的方法,这样就对应起来了。

?而上面Activity的retainNonConfigurationInstances()方法是底层AMS调用的。只要activity没有完全销毁,这个就会存在内存中。

最后一个问题,viewmodelStore上面时候清除数据:CompoentActivity构造方法的一段代码

?我们的activity的销毁onDestory是有两种情况,正常退出或者配置发生变更有可能会(如翻转屏幕)

四、总结

?viewmodel的源码就是以上,可能会有点乱,我会重新梳理一遍的。今天国庆节,国庆节快乐!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-02 14:59:33  更:2021-10-02 14:59:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:51:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码