专栏首页我就是马云飞Architecture Components ViewModel的控制。

Architecture Components ViewModel的控制。

前言

作为MVVM 系列的第二篇,我们来看一下之前提出的第二个问题,就是ViewModel是如果控制生命周期的,并且保证在一定范围内的唯一性。

ViewModel的生命周期

先上一张官方的生命周期的图:

可以看到ViewModel只有一个生命周期函数,那就是onCleared(),会在Activity的onDestroy之后执行, 那么相对应Fragment的生命周期是再哪个函数之后执行?这里先剧透一下,也是在onDestroy之后执行。

在看官方的实现之前,我们先简单的想一下怎么才能实现Activity/Fragment生命周期函数的监听?思考三秒钟,联想到上一篇中的做法,可以想到利用Fragment和Activity中添加的Fragment来感知宿主的生命周期。并且这里我们只需要监听销毁时候的函数就行。下面进行具体的分析。

ViewModel的实现过程

给出一个最简单的创建的示例:

MainActivityViewModel viewModel=ViewModelProviders.of(this).get(MainActivityViewModel.class);

代码很好理解,获取当前类的ViewModel提供者,之后在传入需要获得的ViewModel的类型。先看一下ViewModelProviders都做了什么?

如果传入的this是Fragment就先判断下是否已经关联到Activity上,没有就抛异常。之后就初始化一个sDefaultFactory,用于创建ViewModelProvider。在ViewModelProvider的构造函数中还需要一个ViewModelStores。

两个工厂方法用于创建ViewModelStore。接下来就是本文的重点了。还是以Activity为例,Fragment的大同小异。

简单说一下这个方法都做什么了。先获取FragmentManager,查找当前的Activity有没有已经添加过HoldFragment,没有的话则去还没有添加到Activity/Fragment的HoldFragment列表中去查询,看看有没有已经创建的HoldFragment,只不过还没有添加上去。如果还没有的话那就创建一个新的HoldFragment,同时给Application注册一个Activity的生命周期监听,再把创建的HoldFragment添加到缓存列表中。现在来看看这个HoldFragment。

拥有两个属性sHoldFragmentManager和mViewStore。在onCreate方法中执行一个函数,将在未添加到Activity/Fragment的HoldeFragment列表中删除当前的Activity/Fragment。然后在onDestory方法中调用mViewStore的clear方法,这里就会间接的调用到ViewModel的onCleared()方法。更多的细节可以去看源码,这里简单的总结一下都做了什么。

  1. 查找当前的Activity/Fragment中是否有已经添加的HoldFragment,有则返回。
  2. 查找当前的Activity/Fragment是否有已经创建但是并未添加的HoldFragment,有则返回。
  3. 注册Activity/Fragment的生命周期监听。
  4. 创建新的HoldeFragment,并添加的缓存列表。
  5. HoldFragment在关联到Activity/Fragment之后会在缓存中去掉当前的Activity/Fragment对应的HoldFragment
  6. HoldFragment在onDestory的时候会调用其成员变量mViewStore的clear方法。

回到之前创建ViewModelProvider的地方。

简单看一下,代码不难理解,先赋值成员变量,之后是查看ViewModelStore中是否有传入类型的ViewModel,没有的话就通过传入的工厂类创建一个新的ViewModel 添加到ViewModelStore中。

这样ViewModel的实现过程就差不多结束了,还是利用Fragment的方式去获取生命周期,然后再利用工厂类来创建ViewModel。

关于在一定范围内的唯一性,因为ViewModelStore是HoldFragment的成员变量,HoldFragment是通过FragmentManager添加到指定的Activity/Fragment,那么对于当前的宿主,只有一个HoldFragment,也就只有一个ViewModelStore,同时也就只有一个ViewModel。

总结

同样使用的给宿主添加Fragment的方式来获取宿主的生命周期,只不过现在只获取销毁的函数就可以。然后在HoldFragment中持有一个集合用于保存当前宿主的ViewModel,在onDestory函数中调用集合的clear方法,间接调用到ViewModel的onCleared方法,实现生命周期的控制。同时使用TAG的方式添加Fragment 使得ViewModel相对宿主是唯一的。

本文分享自微信公众号 - 我就是马云飞(coding_ma),作者:one_cup

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-10-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android拾萃- Activity的生命周期和启动模式

    概述 Activity 作为与用户交互的一个窗口,是使用非常频繁的一个基本组件。Android系统是通过Activity栈来管理Activity的,而Activ...

    我就是马云飞
  • Retrofit源码模拟

    如果要进行网络请求,你可能会这样写一个简单的OKHttp请求 public class CallExector { public static fin...

    我就是马云飞
  • Context到底是个啥?

    该类包括了一个真正的Context对象,也就是ContextImpl。其是ContextImpl的代理模式。

    我就是马云飞
  • 使用ELK实时分析SSH暴力破解

    在上一篇《通过rsyslog搭建集中日志服务器》,我们分享了如何通过rsyslog搭建集中日志服务器,收集系统日志,在本篇,我们会利用这些系统日志进行安全分析。

    Bypass
  • ASP.NET Core快速入门(第3章:依赖注入)--学习笔记

    课程链接:http://video.jessetalk.cn/course/explore

    郑子铭
  • 【汽车产业抢占AI赛道】北京汽车产业创新大集参赛项目盘点

    作者:张乾 【新智元导读】12月15日,以“跨越创新峡谷·横渡达尔文海”为主题的首届北京汽车产业创新大集在北京汽车集团研发基地举行,新智元创始人兼CEO杨静女士...

    新智元
  • 【利用Python进行数据分析】3-Python的数据结构、函数和文件

    元组是一个固定长度,不可改变的Python序列对象,创建元组的最简单方式,是用逗号分隔一列值。当用复杂的表达式定义元组,最好将值放到圆括号内。

    用户7886150
  • 还在使用SimpleDateFormat?你的项目崩没?

    日常开发中,我们经常需要使用时间相关类,说到时间相关类,想必大家对SimpleDateFormat并不陌生。主要是用它进行时间的格式化输出和解析,挺方便快捷的,...

    格姗知识圈
  • 还在使用 SimpleDateFormat?你的项目崩没?

    日常开发中,我们经常需要使用时间相关类,说到时间相关类,想必大家对SimpleDateFormat并不陌生。主要是用它进行时间的格式化输出和解析,挺方便快捷的,...

    芋道源码
  • Java8新特性

    1. Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 中的默认方法与静态方法 6....

    用户1212940

扫码关注云+社区

领取腾讯云代金券