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";

    @Override
    protected 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() {
            @Override
            public void onClick(View v) {
                score++;
                tvScore.setText(String.valueOf(score));
            }
        });
        Log.i(TAG,"onCreate");
    }

    @Override
    protected 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">

    <TextView
        android: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" />

    <Button
        android: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;

    @Override
    protected 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() {
            @Override
            public void onClick(View v) {
                myViewModel.addScore();
                tvScore.setText(String.valueOf(myViewModel.getScore()));
            }
        });
        Log.i(TAG,"onCreate");
    }

    @Override
    protected 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++;
    }


    @Override
    protected void onCleared() {
        Log.i(TAG,"在这儿添加释放资源的代码");
        super.onCleared();
    }
}

 运行效果:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值