Android mvvm框架之ViewModel篇

本文详细探讨了Android MVVM框架中的ViewModel组件,分析了ViewModel解决配置变化导致的数据丢失问题及其生命周期。通过ViewModelStore和ViewModelProvider,揭示了ViewModel如何实现与Activity或Fragment的生命周期同步,并讨论了多Controller共享ViewModel的实现方式。此外,文章还涉及到了工厂模式在ViewModel实例化中的应用。
摘要由CSDN通过智能技术生成

目录



1 什么是 ViewModel[Top]

1.1 先考虑两个场景
  • 场景一:我们开发的 APP 可以转屏,转屏后将触发 Controller(Activity or Fragment) 的重建,为了维护转屏前后数据的一致性,我们要么将需要维护的数据以 Bundle 的形式在 onSaveInstance 中保存,必要的时候需要对复合数据实现繁琐的 Parceable 接口,如果数据量太大则我们必须将数据持久化,在转屏后重新拉取数据(from database or networks);
  • 场景二:我们的 Activity 中同时维护了多个 Fragment,每个 Fragment 需要共享一些数据,传统的做法是由宿主 Activity 持有共享数据,并暴露数据获取接口给各个寄生 Fragment。
1.2 缺点

随着业务规模的扩大,以上的两种场景在传统实现方法中显得越来越繁琐且不易维护,且数据模块不易独立进行测试。

1.3 特别说明

关于场景一,同样的场景还适用于各种配置相关的信息发生变化的情况,比如键盘、系统字体、语言区域等,它们的共同作用是都会导致当前 Controller 的重建。

1.4 ViewModel 解决的问题

ViewModel 是 android 新的 mvvm 框架的一部分,它的出现就是为了解决以上两个场景中数据与 Controller 耦合过度的问题。其 基本原理 是:维护一个与配置无关的对象,该对象可存储 Controller 中需要的任何数据,其生命周期与宿主 Controller 的生命周期保持一致,不因 Controller 的重建而失效(注意:Controller 的重建仍然在 Controller 生命周期内,并不会产生一个新的生命周期,即 Controller 的 onDestroy 并不会调用)

这意味着无论是转屏还是系统字体变化等因配置变化产生的 Controller 重建都不会回收 ViewModel 中维护的数据,重建的 Controller 仍然可以从同一个 ViewModel 中通过获取数据恢复状态。



2 ViewModel 实现原理[Top]

2.1 ViewModel 类

如果大家去看一下 ViewModel 类的实现,会发现虽然它是一个 abstract 类,但是没有暴露任何外部可访问的方法,其预留的方法都是 package 访问权限的,
其预留了一些数据清理工作的功能,推测可能是系统保留用作以后扩展,因为与我们对 ViewModel 原理的理解没有什么关联,我们暂且略过。

2.2 ViewModel 的构造过程

我们用一个结构图来剖析 ViewModel 的构造过程:

在这里插入图片描述

如图所示:

  • 所有已经实例化的 ViewModel 都缓存在一个叫做 ViewModelStore 的封装对象中,其实质是一个 HashMap;
  • ViewModelStore 与具体的 Controller 绑定,并与宿主 Controller 俱生俱灭,所以这就解释了为何 ViewModel 与宿主 Controller 的生命周期是一样长了,因为缓存它的 ViewModelStore 与宿主 Controller 寿命相等;
  • 获取 ViewModel 实例的过程委托给了一个叫做 ViewModelProvider 的工具类,它包含一个创建 ViewModel 的工厂类 Factory 和一个对 ViewModelStore 的引用;
  • 总的构造过程为:先从 ViewModelStore 中获取缓存的 ViewModel,若没有缓存过则用 Facotry 实例化一个新的 ViewModel 并缓存,具体的过程分为 4 步,具体可参考图示。

本小节剩下部分分析源码,对于只关心原理的同学此部分可以略过:

我们在获取 ViewModel 的时候,一般通过如下方式:

// 在 Controller(这里以 Fragment 为例)的 onCreate 方法中调用
final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);

我们看一下 ViewModelProviders.of() 的实现:

public static ViewModelProvider of(@NonNull Fragment fragment) {
   
    return of(fragment, null);
}
public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) 
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值