ViewModel 原理

# ViewModel 原理

在现代Android应用开发中,ViewModel是架构组件库的一个关键部分,它在提高应用的稳定性和性能方面发挥着重要作用。在这篇文章中,我们将深入探讨ViewModel的工作原理和最佳实践。

ViewModel简介

ViewModel是Android Jetpack架构组件的一部分,它的主要目的是管理和存储与UI相关的数据。ViewModel的设计初衷是使数据能够在配置更改(如屏幕旋转)后继续存在。

工作原理

数据持久性

  • 当设备配置更改导致Activity重建时,ViewModel可以保留数据。它是通过系统保存的实例状态来实现的,从而使数据在Activity重新创建时依然可用。

生命周期意识

  • ViewModel与Activity或Fragment的生命周期紧密相连。它在Activity或Fragment的整个生命周期内都是活跃的,并在它们被完全销毁时清理。

使用ViewModel的优势

  • 数据管理:ViewModel使得管理UI相关的数据更加简单和高效。
  • 减少内存泄漏:由于ViewModel与视图的生命周期是分离的,因此减少了因为持有Activity或Fragment引用而导致的内存泄漏的风险。
  • 更好的数据持久化:ViewModel可以在配置更改时保留重要数据,避免了不必要的数据库或网络请求。

实现ViewModel

创建ViewModel类

  • ViewModel的创建需要继承ViewModel类。
  • 可以在ViewModel内部实现数据的加载和处理逻辑。

与Activity或Fragment关联

  • ViewModel通过ViewModelProvider与Activity或Fragment绑定。
  • 这样可以确保ViewModel的生命周期与Activity或Fragment的生命周期同步。

处理配置更改

  • 在配置更改(如屏幕旋转)时,ViewModel帮助保存重要的UI数据。
  • 当Activity或Fragment重新创建时,可以从ViewModel中恢复数据。

最佳实践

  • 避免在ViewModel中引用视图:ViewModel不应持有对Activity、Fragment或View的引用。
  • 使用LiveData:LiveData可以用来观察数据的变化,并在数据变化时更新UI。
  • 分离关注点:ViewModel应该专注于数据处理,而UI逻辑应该留在Activity或Fragment中。

ViewModel的创建方式

1. 使用ViewModelProvider

这是创建ViewModel的最常见方式。ViewModelProvider会与Activity或Fragment的生命周期关联,确保在配置更改时ViewModel不会被重新创建。

import androidx.lifecycle.ViewModelProvider
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundleclass MainActivity : AppCompatActivity() {private lateinit var viewModel: MyViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)viewModel = ViewModelProvider(this).get(MyViewModel::class.java)}
}

在这个例子中,MyViewModel 是通过ViewModelProvider创建的,并与MainActivity的生命周期关联。

2. 使用ViewModel的工厂方法

当需要向ViewModel传递参数时,可以使用ViewModel的工厂方法来创建ViewModel。

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundleclass MyViewModel(val myParam: String) : ViewModel() {// ViewModel的逻辑
}class MyViewModelFactory(private val myParam: String) : ViewModelProvider.Factory {override fun <T : ViewModel?> create(modelClass: Class<T>): T {if (modelClass.isAssignableFrom(MyViewModel::class.java)) {return MyViewModel(myParam) as T}throw IllegalArgumentException("Unknown ViewModel class")}
}class MainActivity : AppCompatActivity() {private lateinit var viewModel: MyViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val factory = MyViewModelFactory("Hello")viewModel = ViewModelProvider(this, factory).get(MyViewModel::class.java)}
}

在这个例子中,MyViewModel 需要一个字符串参数。因此,创建了一个MyViewModelFactory
来传递这个参数,并使用这个工厂来创建MyViewModel的实例。


ViewModel 相关面试题及回答

面试题1: ViewModel是什么,它是如何工作的?

  • 回答:
    ViewModel是一个架构组件,它的主要职责是管理界面控制器(如Activity和Fragment)的数据。它帮助保存数据,以便在配置更改(如屏幕旋转)时数据不会丢失。ViewModel的实例与特定的Activity或Fragment的生命周期绑定,但比单个Activity或Fragment的实例生命周期更长,因此能够在界面控制器重建时保持数据状态。

面试题2: 为什么在ViewModel中持有Activity的引用是一个不好的实践?

  • 回答:
    在ViewModel中持有Activity的引用会导致内存泄露,因为ViewModel的生命周期比它所关联的Activity长。如果ViewModel持有Activity的引用,即使Activity需要被销毁以释放资源,由于ViewModel的存在,它无法被垃圾回收器回收,从而导致内存泄漏。

面试题3: LiveData是什么,它如何与ViewModel配合使用?

  • 回答:
    LiveData是一个可观察的数据存储器类,特别是用于保存可观察数据,并且能在数据改变时通知视图。它与ViewModel配合使用,因为LiveData遵循观察者模式,这使得当数据改变时,UI可以立即更新。LiveData也是生命周期感知的,这意味着它只会在Activity或Fragment处于活跃状态时更新UI,从而避免内存泄漏。

面试题4: 如何在ViewModel中处理耗时任务?

  • 回答:
    在ViewModel中处理耗时任务(如网络请求)时,应该使用后台线程来避免阻塞UI线程。可以利用协程或RxJava等异步处理框架来实现。这些任务应该与ViewModel的生命周期关联,以确保在ViewModel被销毁时,相关的异步任务也会相应地被取消或清理,以避免内存泄露。

面试题5: 解释ViewModel的onCleared()方法。

  • 回答: onCleared()
    方法在ViewModel即将被销毁时调用,这通常发生在与其关联的Activity或Fragment被永久销毁时(不是由于配置更改)。这个方法是清理资源的理想位置,比如取消所有进行中的异步任务、移除监听器或者释放对外部资源的引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/496643.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图论(算法竞赛、蓝桥杯)--Dijkstra算法最短路

1、B站视频链接&#xff1a;D02 最短路 Dijkstra 算法_哔哩哔哩_bilibili 题目链接&#xff1a;【模板】单源最短路径&#xff08;弱化版&#xff09; - 洛谷 #include <bits/stdc.h> using namespace std; #define INF 2147483647 int n,m,s,a,b,c; const int N100010…

c++学习记录 vector容器—赋值操作

函数原型&#xff1a; vector& operator(const vector& vec); //重载等号操作符assign(beg,end); //将[beg,end)区间中的数据拷贝赋值给本身assign(n,elem); //将n个el…

DAY12_VUE基本用法详细版

目录 0 HBuilderX酷黑主题修改注释颜色1 VUE1.1 VUE介绍1.2 Vue优点1.3 VUE入门案例1.3.1 导入JS文件1.3.2 VUE入门案例 1.4 VUE基本用法1.4.1 v-cloak属性1.4.2 v-text指令1.4.3 v-html指令1.4.4 v-pre指令1.4.5 v-once指令1.4.6 v-model指令1.4.7 MVVM思想 1.5 事件绑定1.5.1…

使用空闲电脑免费搭建一个私人的网盘

如果你也有一台空闲电脑&#xff0c;可以使用它来搭建一个私人的网盘。 这里使用的是飞梦云网盘&#xff1b; 服务端&#xff1a;下载 服务器文件使用hash校验进行储存&#xff0c;实现重复上传的文件秒传功能。 Fuse4Ui&#xff08;虚拟分区工具&#xff09;&#xff1a;下…

算法沉淀——动态规划之回文串问题(上)(leetcode真题剖析)

算法沉淀——动态规划之回文串问题 01.回文子串02.最长回文子串03.分割回文串 IV04.分割回文串 II05.最长回文子序列06.让字符串成为回文串的最少插入次数 01.回文子串 题目链接&#xff1a;https://leetcode.cn/problems/palindromic-substrings/ 给你一个字符串 s &#xf…

Django定时任务之django_apscheduler使用

Django定时任务之django_apscheduler使用 今天在写一个任务需求时需要用到定时任务来做一部分数据处理与优化&#xff0c;于是在了解完现有方法&#xff0c;结合自己需求决定使用django_apscheduler&#xff0c;记录一下过程&#xff0c;有几篇值得参考的文章放在结尾&#xf…

python|闲谈2048小游戏和数组的旋转及翻转和转置

目录 2048 生成数组 n阶方阵 方阵旋转 顺时针旋转 逆时针旋转 mxn矩阵 矩阵旋转 测试代码 测试结果 翻转和转置 2048 《2048》是一款比较流行​的数字游戏​&#xff0c;最早于2014年3月20日发行。原版2048由Gabriele Cirulli首先在GitHub上发布&#xff0c;后被移…

云计算新宠:探索Apache Doris的云原生策略

文章目录 Apache Doris 特性极简架构高效自运维高并发场景支持MPP 执行引擎明细与聚合模型的统一便捷数据接入 Apache Doris 极速 1.0 时代极速列式内存布局向量化的计算框架Cache 亲和度虚函数调用SIMD 指令集 稳定多源 关于 Apache Doris 开源社区基于云原生向量数据库Milvus…

搜维尔科技:CATIA为建筑、基础设施和城市规划提供虚拟孪生力量

超越传统项目交付方法限制的协作 复杂建筑和基础设施项目开发的设计和工程流程需要多个利益相关者和所有项目阶段的密切合作。此外&#xff0c;日益复杂的施工项目要求所有团队都依赖 CATIA 和3D EXPERIENCE 虚拟孪生技术作为“通用语言”&#xff0c;以促进协作并减少阶段之间…

【OneAPI】节假日查询API

OneAPI新接口发布&#xff1a;节假日查询API 可查询指定月份、年份法定节假日及调休情况。 API地址&#xff1a;https://oneapi.coderbox.cn/openapi/public/holiday 请求参数 URL参数 参数名类型必须含义说明datestring否要查询的日期可按年或月查询&#xff0c;支持前缀…

如何获取Cookie??

在学习Servlet的时候&#xff0c;我们便学习过如何获取Cookie&#xff0c;我们来回顾以下吧&#xff01; RestController RequestMapping("/param") public class ParamController {//如何获取CookieRequestMapping("/getCookie")public String getCookie…

[计算机网络]--MAC/ARP/DNS协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、认识以…