Jetpack组件---ViewModel

1.什么是ViewModel

对于Android传统的代码编写方式,一般地,将页面UI的处理,数据的加载,全部放在Activity或Fragment中进行,但这并不满足“单一功能原则”,也不易于维护和扩展。我们应该将项目结构进行分层,传统的MVC,MVP和MVVM,都是将项目结构分了三层,“各管一摊”,这三种模式各有特点、各有利弊,但它们都有一个共同点,就是区分出了M层与V层,M即Model层,V即View层,M层负责数据的处理,View层负责UI的展示,不同的地方在于如何将M层与V层进行结合。
其中,MVVM模式除了M层和V层之外,就是VM层,即ViewModel。
Jetpack为开发者提供了ViewModel的概念,将页面所需要的数据从V层和M层中剥离出来,ViewModel是介于View层和Model层的一个桥梁,使得视图和数据即区分开来,又能保持联系。在 Android 中,ViewModel 的作用就是在 UI 控制器(如 Activity、Fragment)的生命周期中保存和管理 UI 相关的数据。ViewModel 保存的数据在配置更改(如屏幕旋转)后会依然存在,不会丢失。

2.ViewModel的使用场景

  • 防止因屏幕旋转导致 Activity 重建而丢失数据
  • 同一 Activity 中不同 Fragment 间数据共享
  • 防止销毁的 Activity 中未完成的异步回调

3.ViewModel的生命周期

当Android应用程序退回到桌面,或者横竖屏切换时,Activity等组件可能会丢失状态或者是被销毁,这时,开发者通常需要考虑数据的保存和恢复,常见的就是通过onSavaInstanceState()方法和onRestoreInstanceState()方法来实现,有了ViewModel,就可以用更简单的方法来保存数据了。这是为什么呢?
ViewModel独立于组件的配置的变化,也就是说,当发生特殊情况导致Activity重新执行某些生命周期时,ViewModel的生命周期并不会发生变化。
下图是ViewModel与Activity的生命周期的对应关系:

在这里插入图片描述

4.源码分析

4.1.为什么 ViewModel 可以防止因屏幕旋转导致 Activity 重建而丢失数据

获取 ViewModel 实例对象需要通过如下代码:

val model = ViewModelProvider(this).get(ShareViewModel::class.java)

在 ViewModelProvider 的构造函数中,主要是为 ViewModelStore、Factory 两个变量赋值。
先看下 ViewModelStore,其中包含一个 HashMap 存储 ViewModel,还有put()、get()、clear() 函数,put 和 get 函数都是在 ViewModelProvider 的 get 函数中调用,clear 函数是在 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()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });
}

这里看到调用 clear 函数的前提非改变配置导致的页面重建 。这就解释了为什么 ViewModel 可以防止因屏幕旋转导致 Activity 重建而丢失数据了。

4.2.同一Activity 中不同 Fragment 间数据共享

不同 Fragment 间数据共享的重点是,获取他们所共同依赖的 Activity 中保存的 ViewModelStore,只有这样才可以得到 ViewModel 的同一实例对象,再配合 LiveData 即可实现数据变化的监听。

4.3.防止销毁的 Activity 中未完成的异步回调

其实来说 ViewModel 自身的功能只有两个

  • 防止因屏幕旋转导致 Activity 重建而丢失数据。
  • 同一 Activity 中不同 Fragment 间数据共享。

防止销毁的 Activity 中未完成的异步回调,这个功能是配合 LiveData 实现的。异步回调结果修改 LiveData 数据,通过观察者监听 LiveData 数据的修改更新 UI 显示,在 LiveData 篇章中可以知道当页面销毁时观察者删除,如此防止调用销毁页面的 UI。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值