JetPack之ViewModel

目录

  • 一、简介
    • 1.1 优点
    • 1.2 生命周期
  • 二、使用
    • 2.1 ViewModel保证数据稳定性demo
    • 2.2 ViewModel中如何传递上下文Context
  • 三、注意点


一、简介

ViewModel 组件用于管理界面相关的数据,并且在配置更改(如屏幕旋转)时保持数据的一致性。ViewModel 组件的详细解释如下:

  • 作用
    ViewModel 用于存储和管理界面相关的数据,如 UI 元素的状态、用户交互数据等。
    通过 ViewModel 可以在界面控制器(如 Activity 或 Fragment)之间共享数据,而无需担心生命周期问题。
  • 特点
    ViewModel 对象会在相关的 Activity 或 Fragment 生命周期内保持不变,即使配置更改也不会丢失数据。
    ViewModel 不持有对界面控制器的引用,因此不会造成内存泄漏。
    ViewModel 适用于存储大量数据或需要跨界面共享的数据。
  • 使用方法
    在 Activity 或 Fragment 中通过 ViewModelProvider 获取 ViewModel 对象。
    在 ViewModel 中编写逻辑代码,如数据获取、数据处理等。
    在界面控制器中观察 ViewModel 中的数据变化,并更新 UI。

画一个简单示意图
在这里插入图片描述

1.1 优点

使用 ViewModel 来保存和管理应用程序的数据具有以下好处:

  • 生命周期感知:ViewModel 对象会感知与其关联的 Activity 或 Fragment 的生命周期,并在这些组件被销毁时保留数据状态。这样可以避免在配置更改或屏幕旋转等情况下丢失数据。
  • 数据共享:ViewModel 可以在不同的组件之间共享数据,例如在 Fragment 和 Activity 之间共享数据。这样可以避免数据重复加载和保持数据一致性。
  • 避免内存泄漏:使用 ViewModel 可以避免由于内存泄漏而导致的性能问题。ViewModel 会在不再需要时自动清理资源,确保不会造成内存泄漏。
  • 简化代码:将数据存储和管理的责任交给 ViewModel,可以使代码更加清晰和简洁。ViewModel 可以帮助分离数据处理逻辑和 UI 展示逻辑,提高代码的可维护性和可读性。
  • 支持配置更改:ViewModel 可以帮助应对配置更改(如屏幕旋转)时的数据保存和恢复问题,确保用户体验的连续性。

1.2 生命周期

在这里插入图片描述


二、使用

2.1 ViewModel保证数据稳定性demo

用一个简单得例子比较使用ViewModel保存数据的好处
MyViewModel
继承自ViewModel ,写一个int型属性

public class MyViewModel extends ViewModel {

    public int number = 0;
    /**
     * 释放资源
     */
    @Override
    protected void onCleared() {
        super.onCleared();
    }
}

ViewModelActivity
两个方法,分别用NoViewModel和UseViewModel观察在横竖屏情况下显示数据的稳定性

public class ViewModelActivity extends AppCompatActivity {
    ActivityViewmodelBinding binding;
    private MyViewModel myViewModel;

    private int mynumber = 0;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityViewmodelBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        myViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory())
                .get(MyViewModel.class);

        NoViewModel();
    }

    public void NoViewModel() {
        binding.viewmodeltext.setText(String.valueOf(mynumber));
        binding.viewmodel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binding.viewmodeltext.setText(String.valueOf(++mynumber));
            }
        });
    }

    public void UseViewModel() {

        binding.viewmodeltext.setText(String.valueOf(myViewModel.number));
        binding.viewmodel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                binding.viewmodeltext.setText(String.valueOf(++myViewModel.number));
            }
        });
    }

}

NoViewModel
在这里插入图片描述
UseViewModel
在这里插入图片描述
怎么样?对比是不是很明显。

2.2 ViewModel中如何传递上下文Context

ViewModel既然能管理我们的数据,那么Activity、Fragment中数据的传递必然会用到上下文Context了,ViewModel如何去获取呢?
这时候需要继承的对象不再是ViewModel了,而是AndroidViewModel
在这里插入图片描述
根据提示完成构造器
在这里插入图片描述
在构造器中传递context,当后续使用context的时候便可以使用了。

public class MyViewModel extends AndroidViewModel {

    Context context;
    
    public int number = 0;

    public MyViewModel(@NonNull Application application) {
        super(application);
         context =application;
    }
}

三、注意点

在开发中不会单独使用ViewModel ,一般是与LiveData等其他JetPack组件综合使用的,以下是ViewModel 使用过程中的注意事项:

  • 生命周期感知:ViewModel 是与生命周期绑定的,因此应该避免在 ViewModel 中持有对界面元素(如 Activity、Fragment)的引用,以防止内存泄漏。如果需要使用 Context,请考虑使用 Application Context 或者 AndroidViewModel。
  • 避免存储大量数据:ViewModel 主要用于存储与界面相关的数据,不应该存储大量数据或长期保持数据。对于大量数据或需要长期保存的数据,应该考虑使用其他方式,如 Room 数据库。
  • 避免过度耦合:ViewModel 应该专注于管理界面相关的数据和业务逻辑,而不应该包含太多与界面无关的逻辑。保持 ViewModel 的职责单一,可以使代码更易于维护和测试。
  • 使用 LiveData:ViewModel 中通常会使用 LiveData 来持有数据,以便在数据发生变化时通知界面更新。LiveData 具有生命周期感知能力,可以确保数据更新时只通知处于活动状态的界面。
  • 避免内存泄漏:在编写 ViewModel 时,要注意避免引起内存泄漏的情况。确保及时释放资源和取消不再需要的订阅或回调,以避免造成内存泄漏。

参考链接:
ViewModel的基本使用
ViewModel简单使用与解析
深入理解与运用Android Jetpack ViewModel

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不可变集合及Stream流

若希望某个数据是不可修改的,就可以考虑使用不可变集合,以提高安全性;(JKD9之后才有) List不可变集合: public static void main(String[] args) {/*创建不可变的List集合"张三", "李四&q…

快速修复找不到msvcp140.dll,无法继续执行此代码问题

在电脑使用过程中,我们经常会遇到一些错误提示,其中之一就是“无法找到msvcp140.dll”的错误。那么,msvcp140.dll究竟是什么呢?它为什么会出现这样的错误呢?通过查阅资料和自己的实践经验,我对msvcp140.dll…

odoo 官方常用 widgets 小部件清单

在Odoo中,小部件(Widgets)是用于构建用户界面的组件,它们决定了表单、列表视图以及更多交互元素的显示和行为方式。虽然无法提供Odoo14及之后所有版本的确切小部件清单,但可以列举一些常见和重要的内置小部件类型&…

11.创建后台系统项目

后台系统项目 兼容性 vite官网:https://vitejs.dev/ vite中文网:https://cn.vitejs.dev/ vite需要node.js版本 >14.0.0,建议16 node -v 查看版本号 创建项目 进入存放目录 执行命令 npm create vitelatest 选择vue框架 选择typescript…

V R元宇宙平台的未来方向|V R主题馆加 盟|游戏体验馆

未来,VR元宇宙平台可能会呈现出以下发展趋势和可能性: 全面融合现实与虚拟世界: VR元宇宙平台将更加无缝地融合现实世界和虚拟世界,用户可以在虚拟环境中进行各种活动,与现实世界进行互动,并且体验到更加逼…

【PostGresql】------ pg多表数据多个条件汇总 使用 union 方法示例代码

1. 示例代码如下: SELECT"ID","DT_DATE","CNAME","RMAN_NAME","DEP_NAME","DEP_ID","INVEST_MAN_NAME","TYPE_NAME","INVEST_LEVEL_NAME","POSITION_NAME",…

详细教程与使用指南助您轻松上手Sora

在2024年2月16日,OpenAI团队宣布了一项革命性的技术突破——推出了首个能够将文本描述转化为视频内容的人工智能模型,名为Sora。这一创新标志着人工智能在多媒体内容创作领域迈出了重要一步。Sora模型不仅能够根据用户的文字描述生成长达60秒的动态视频&…

复习Day3

1231. 航班时间 - AcWing题库 #include<bits/stdc.h> using namespace std; int getTime(){//得到时间 int h1,m1,s1,h2,m2,s2,d0;scanf("%d:%d:%d %d:%d:%d (%d)",&h1,&m1,&s1,&h2,&m2,&s2,&d);//补匹配直接跳过 int timed*24*3…

leetcode 1047. 删除字符串中的所有相邻重复项

题目 思路 这是一道easy题&#xff0c;很明显要用栈。 有三种情况&#xff1a; 如果栈空&#xff0c;则直接入栈。 如果栈顶元素和当前元素不同则入栈。 如果栈顶元素和当前元素相同则栈顶元素出栈 最后再将栈中的元素依次pop&#xff0c;添加到一个字符串中就行。 代码…

Java设计模式 | 抽象工厂模式

抽象工厂模式 工厂方法模式中考虑的是一类产品的生产&#xff0c;如幼儿园只培养小朋友&#xff0c;鞋厂只生产鞋子。这些工厂只生产同种类产品&#xff0c;同种类产品称为同等级产品&#xff0c;即工厂方法模式只考虑生产同等级的产品&#xff0c;但是在现实生活中许多工厂都…

一文搞懂数据链路层

数据链路层 1. 简介2. MAC3. 以太网 1. 简介 &#xff08;1&#xff09;概念 链路(link)是一条无源的点到点的物理线路段&#xff0c;中间没有任何其他的交换结点。 数据链路(data link) 除了物理线路&#xff08;双绞线电缆、同轴电缆、光线等介质&#xff09;外&#xff0…

利用LoadRunner 测试MySQL Server 性能

1&#xff09;将本次实验材料文件夹中bin文件夹和 include文件夹下文件分别拷贝到 LoadRunner 安装路径下的 bin 文件夹和下include文件夹下。 2&#xff09;在mysql中创建相应的数据库和表(创建数据库的和表的脚本在附录2中) 3&#xff09;机房mysql启动需要在winr之后输入ser…

刷题日记——BFS:离开迷宫最短时间、生化武器(天津大学/南开大学机试)

例题 分析 需要注意地图的输入&#xff0c;每一行都有个换行符&#xff0c;需要扔掉写完地图的输入&#xff0c;最好输出一下验证一下输入的对不对由于是求最短的时间&#xff0c;BFS第一次找到终点就输出即可考虑到连续输入多个样例的可能性&#xff0c;如果选择找到终点就输…

手撕算法-二叉树的层平均值

描述 分析 二叉树的层序遍历。层序遍历需要用到队列。 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, T…

阿里云ECS服务器u1通用算力型CPU性能如何?

阿里云服务器u1是通用算力型云服务器&#xff0c;CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器&#xff0c;通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xff0c…

java画各种卡通人物图

需要可以关注加q:2430486030

【数据结构】快速排序(不用递归)

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解快速排序的非递归方法&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 上一篇博客我们讲了如何实现使用递归的快速排序&#xff0c;今天我们再来了解一下如何…

进程等待与进程程序替换

一、进程等待 1.进程等待的必要性 &#xff08;1&#xff09;子进程退出&#xff0c;父进程如果不管不顾&#xff0c;就可能造成‘僵尸进程’的问题&#xff0c;进而造成内存泄漏。 &#xff08;2&#xff09;另外&#xff0c;进程一旦变成僵尸状态&#xff0c;那就刀枪不入&…

unity学习(67)——控制器Joystick Pack方向

1.轮盘直接复制一个拖到右边就ok了&#xff0c;轮盘上是有脚本的。&#xff08;只复制&#xff09; 2.上面的显示窗也可以复制&#xff0c;但是要绑定对应的轮盘&#xff08;unity中修改变量&#xff09;&#xff0c;显示窗上是有脚本的。&#xff08;复制改变量&#xff09; 3…