前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Jetpack】ViewModel 架构组件 ( 视图 View 和 数据模型 Model | ViewModel 作用 | ViewModel 生命周期 | 代码示例 | 使用注意事项 )

【Jetpack】ViewModel 架构组件 ( 视图 View 和 数据模型 Model | ViewModel 作用 | ViewModel 生命周期 | 代码示例 | 使用注意事项 )

作者头像
韩曙亮
发布2023-03-30 19:20:01
7840
发布2023-03-30 19:20:01
举报

文章目录

一、Activity 遇到的问题


Activity 遇到的问题 :

  • 瞬态数据丢失 : 操作 Activity 时 , 如果 屏幕 自动旋转 , 当前 Activity 组件会 执行销毁操作 , 并重新创建新的 Activity 组件 , 该操作会 导致 Activity 的 瞬态数据 丢失 ;
  • 内存泄漏 : 在 系统组件 如 Activity 中 , 启动了一个线程 , 在线程中执行一系列操作 , 如果 Activity 在线程停止前销毁 , 那么 从 Activity 销毁 到 线程停止前 的这一段时间 , 就出现了内存泄漏问题 ;
  • 组件代码量大 : 在 Activity 中写了大量的代码 , 导致 可维护性 降低 , 测试难度 增加 ;

二、视图 View 和 数据模型 Model


在 Activity 中 , 存在两种元素 , 视图 View 和 填充视图数据用的 数据模型 Model ;

如果将 视图 和 数据模型 都写在 Activity 中 , 二者 耦合程度很高 ,

此时 , 就会造成上述 Activity 的三大问题 : ① 丢失瞬态数据 , ② 内存泄漏 , ③ 组件代码量大 ;

三、ViewModel 架构组件作用


为了解决上述问题 , 提出了 ViewModel 架构组件 ,

该组件 是 视图 View 和 数据模型 Model 之间 的 沟通桥梁 ;

借助 ViewModel , 视图 与 数据模型 实现了 解耦 , 同时 还能保证 视图 与 数据模型 之间 保持 通信 ;

这样 Activity 的代码量减少了 , 只需要维护 视图 View 相关内容 , 增加了代码的可维护性 , 以及可测试性 ;

在这里插入图片描述
在这里插入图片描述

在 ViewModel 架构中 , 数据 不由 View 直接进行管理 , 而是 由 ViewModel 进行管理 ;

当 Activity 屏幕旋转 , 销毁时 , 只会销毁 Activity 组件 , 不会将 ViewModel 以及 数据模型 Model 销毁 ;

Activity 中的组件 获取数据时 , 不直接从 数据模型 Model 中获取 , 而是 从 ViewModel 架构组件中获取 ;

ViewModel 作用 :

  • 保存瞬态数据
  • 作为 View 视图 与 Model 数据模型 的桥梁
  • 作为 不同的 Activity 或 Fragment 之间沟通的桥梁

四、ViewModel 代码示例


1、ViewModel 视图模型

ViewModel 视图模型 继承 androidx.lifecycle.ViewModel 类 , 在其中定义要维护的数据即可 ;

代码示例 :

代码语言:javascript
复制
package kim.hsl.viewmodeldemo

import androidx.lifecycle.ViewModel

class MyViewModel : ViewModel() {
    var number: Int = 0
}

2、Activity 组件

在 Activity 中 , 要 绑定 ViewModel 组件 , 通过 ViewModelProvider 获取 MyViewModel::class.java 类 对应的 ViewModel 实例对象 ;

代码示例 :

代码语言:javascript
复制
package kim.hsl.viewmodeldemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider

class MainActivity : AppCompatActivity() {

    lateinit var textView: TextView
    lateinit var myViewModel: MyViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 获取布局组件
        textView = findViewById(R.id.textView)

        // 获取 ViewModel
        myViewModel = ViewModelProvider(this,
            ViewModelProvider.AndroidViewModelFactory(application))
            .get(MyViewModel::class.java)

        // 组件中显示 ViewModel 中的内容
        textView.setText("${myViewModel.number}")
    }

    fun onClick(view: View) {
        myViewModel.number++
        textView.setText("${myViewModel.number}")
    }
}

3、UI 布局文件

点击按钮 , 令显示的文本数字自增 ;

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="40sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.3" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="数值自增"
        android:textSize="40sp"
        android:onClick="onClick"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

4、运行效果

在屏幕旋转后 , Activity 销毁重建 , 也没有影响数据运行 , 自增操作没有被打断 ;

请添加图片描述
请添加图片描述

五、ViewModel 生命周期


ViewModel 的 生命周期 与 Activity 或 Fragment 的 生命周期 相互独立 , ViewModel 不受 Activity 组件销毁的影响 ;

如果 由于 屏幕旋转 原因 导致的 Activity 销毁重建 , 与之绑定的 ViewModel 会在销毁时解绑 , Activity 重建时重新绑定 ;

ViewModel 会在 应用生命周期 内存活 , 并且可以在 Activity 或 Fragment 之间共享数据 ;

在这里插入图片描述
在这里插入图片描述

ViewModel 的 生命周期 : 一个 ViewModel 实例对象 可以与 多个 Activity 或 Fragment 绑定 ;

  • 创建 : 在 Activity 的 首次启动时 创建 ViewModel 实例对象 , 如果 Activity 多次启动 , ViewModel 只会创建一次 ;
  • 绑定 : Activity 与 ViewModel 关联时 , 开始绑定 ViewModel , Activity 组件中 绑定 ViewModel 代码如下 ;
代码语言:javascript
复制
        // 获取 ViewModel
        myViewModel = ViewModelProvider(this,
            ViewModelProvider.AndroidViewModelFactory(application))
            .get(MyViewModel::class.java)
  • 解绑 : 当 Activity 或者 Fragment 被销毁时 , 与之绑定的 ViewModel 会与 UI 组件解绑 ;
  • 销毁 : ViewModel 关联的所有的 Activity 或 Fragment 全部销毁 , 则 ViewModel 实例对象 也会被销毁 ;

六、ViewModel 使用注意事项


ViewModel 使用注意事项 :

使用 ViewModel 时 , 不要将 Context 上下文对象传入 ViewModel 中 , 否则会导致内存泄漏 ;

如果要使用 Context 上下文对象 , 则 ViewModel 需要继承 AndroidViewModel 类 , 在 其构造函数 中获取 Application 对象 ;

代码示例 :

代码语言:javascript
复制
package kim.hsl.viewmodeldemo

import android.app.Application
import androidx.lifecycle.AndroidViewModel

class MyViewModel2 : AndroidViewModel {
    constructor(application: Application) : super(application) {
        // 此处可获取 Application 上下文对象
    }
}

博客代码 :

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、Activity 遇到的问题
  • 二、视图 View 和 数据模型 Model
  • 三、ViewModel 架构组件作用
  • 四、ViewModel 代码示例
    • 1、ViewModel 视图模型
      • 2、Activity 组件
        • 3、UI 布局文件
          • 4、运行效果
          • 五、ViewModel 生命周期
          • 六、ViewModel 使用注意事项
          相关产品与服务
          图数据库 KonisGraph
          图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档