Jetpack架构组件_ViewModel组件_1.简介和示例

2024-08-28 15:04

本文主要是介绍Jetpack架构组件_ViewModel组件_1.简介和示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.简介

       ViewModel是我们MVVM中的VM层,ViewModel类似于MVP中的P层,它是我们View层和Model层之间的一个桥梁。

1.1 和MVP的P层的主要区别是:

(1)ViewModel是与我们Android系统挂钩的,是官方的一个类,MV之间的一个桥梁。

(2)ViewModel还保持数据。

1.2 Android为什么要引入ViewModel? 

(1)分层,便于测试和维护;

(2)ViewModel解决了横竖切换时数据丢失的问题。ViewModel生命周期比较长一些,不受横竖屏切换Activity生命周期的影响。

(3)避免因疏忽而导致的内存泄露。onCleared里,写一些释放资源的代码。

1.3 Viewmodel生命周期

         Viewmodel生命周期可以参考官网地址:

ViewModel 概览  |  Android Developers

        图 1 说明了 activity 经历屏幕旋转而后结束时所处的各种生命周期状态。该图还在关联的 activity 生命周期的旁边显示了 ViewModel 的生命周期。此图表说明了 activity 的各种状态。这些基本状态同样适用于 fragment 的生命周期。

图1 ViewModel的生命周期

        通常在系统首次调用 activity 对象的 onCreate() 方法时请求 ViewModel。系统可能会在 activity 的整个生命周期内多次调用 onCreate(),如在旋转设备屏幕时。ViewModel 存在的时间范围是从首次请求 ViewModel 直到 activity 完成并销毁。

 2.代码示例

 2.1新建工程

        选Empty Views Activity。 

项目名:ViewModelDemo ,语言:Java。

 2.2  Activity定义变量

        在activity中定义变量,每次旋转屏幕后会丢失。

        MainActivity.java代码:

package com.gaoting.viewmodeldemo;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {int score;TextView tvScore;Button btAddScore;String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tvScore = this.findViewById(R.id.tvScore);btAddScore = this.findViewById(R.id.btAddScore);btAddScore.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {score++;tvScore.setText(String.valueOf(score));}});Log.i(TAG,"onCreate");}@Overrideprotected void onDestroy() {Log.i(TAG,"onDestroy");super.onDestroy();}
}

        activity_main.xml代码:

<?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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/tvScore"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="成绩:0"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:layout_marginTop="30dp"app:layout_constraintTop_toBottomOf="@+id/tvScore"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"android:text="点我+1"android:id="@+id/btAddScore"android:layout_width="wrap_content"android:layout_height="wrap_content"tools:ignore="MissingConstraints"/></androidx.constraintlayout.widget.ConstraintLayout>

        运行效果:

        点击button,成绩增加到10,然后旋转屏幕发现成绩变成0了。

 2.3变量放在Viewmodel中

         新建MyViewModel类。

         MainActivity.java代码

package com.gaoting.viewmodeldemo;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;public class MainActivity extends AppCompatActivity {TextView tvScore;Button btAddScore;String TAG = "MainActivity";MyViewModel myViewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ViewModelProvider viewModelProvider = new ViewModelProvider(this,new ViewModelProvider.NewInstanceFactory());myViewModel = viewModelProvider.get(MyViewModel.class);tvScore = this.findViewById(R.id.tvScore);tvScore.setText(String.valueOf(myViewModel.getScore()));btAddScore = this.findViewById(R.id.btAddScore);Log.i(TAG,"score init:"+tvScore.getText() +"vm:"+ myViewModel.getScore());btAddScore.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {myViewModel.addScore();tvScore.setText(String.valueOf(myViewModel.getScore()));}});Log.i(TAG,"onCreate");}@Overrideprotected void onDestroy() {Log.i(TAG,"onDestroy");super.onDestroy();}
}

         MyViewModel.java代码:

package com.gaoting.viewmodeldemo;import android.util.Log;import androidx.lifecycle.ViewModel;public class MyViewModel extends ViewModel {int score;public static final String TAG = "MyViewModel";public int getScore() {return score;}public void addScore(){score++;}@Overrideprotected void onCleared() {Log.i(TAG,"在这儿添加释放资源的代码");super.onCleared();}
}

 运行效果:

        如下图所示,可以看到旋转不会丢失数据。

这篇关于Jetpack架构组件_ViewModel组件_1.简介和示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1115101

相关文章

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

golang 日志log与logrus示例详解

《golang日志log与logrus示例详解》log是Go语言标准库中一个简单的日志库,本文给大家介绍golang日志log与logrus示例详解,感兴趣的朋友一起看看吧... 目录一、Go 标准库 log 详解1. 功能特点2. 常用函数3. 示例代码4. 优势和局限二、第三方库 logrus 详解1.

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java异常架构Exception(异常)详解

《Java异常架构Exception(异常)详解》:本文主要介绍Java异常架构Exception(异常),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. Exception 类的概述Exception的分类2. 受检异常(Checked Exception)

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

C#中的 StreamReader/StreamWriter 使用示例详解

《C#中的StreamReader/StreamWriter使用示例详解》在C#开发中,StreamReader和StreamWriter是处理文本文件的核心类,属于System.IO命名空间,本... 目录前言一、什么是 StreamReader 和 StreamWriter?1. 定义2. 特点3. 用