Android-ViewModel & LiveData & DataBinding & ViewModelSavedState & SharedPreferences & 小案例

组件(MVVM)

当我们不适用ViewModel时,是直接对view进行操作,并且数据是直接存储在controller中

ViewModel

ViewModel 将视图的数据和逻辑从具有生命周期特性的实体(如 Activity 和 Fragment)中剥离开来。直到关联的 Activity 或 Fragment 完全销毁时,ViewModel 才会随之消失,也就是说,即使在旋转屏幕导致 Fragment 被重新创建等事件中,视图数据依旧会被保留。ViewModels 不仅消除了常见的生命周期问题,而且可以帮助构建更为模块化、更方便测试的用户界面。

ViewModel的优点也很明显,为Activity 、Fragment存储数据,直到完全销毁。尤其是屏幕旋转的场景,常用的方法都是通过onSaveInstanceState()保存数据,再在onCreate()中恢复,真的是很麻烦。

其次因为ViewModel存储了数据,所以ViewModel可以在当前ActivityFragment中实现数据共享。

  1. ViewModel

    public class MyViewModel extends ViewModel {
          
          
    
        private  int number;
    
        public int getNumber() {
          
          
            return number;
        }
    
        public void setNumber(int number) {
          
          
            this.number = number;
        }
    }
    
  2. MainActivity

    public class MainActivity extends AppCompatActivity {
          
          
    
        private MyViewModel myViewModel;
        private TextView textView;
        private Button button1,button2;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            this.myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
    
            this.textView = findViewById(R.id.textView);
            this.button1 = findViewById(R.id.button1);
            this.button2 = findViewById(R.id.button2);
    
            this.textView.setText(String.valueOf(this.myViewModel.getNumber()));
    
            this.button1.setOnClickListener(v -> {
          
          
                this.myViewModel.setNumber(this.myViewModel.getNumber()+1);
                this.textView.setText(String.valueOf(this.myViewModel.getNumber()));
            });
    
            this.button2.setOnClickListener(v -> {
          
          
                this.myViewModel.setNumber(this.myViewModel.getNumber()+2);
                this.textView.setText(String.valueOf(this.myViewModel.getNumber()));
            });
        }
    }
    

    注意:这里 **this.myViewModel = new ViewModelProvider(this).get(MyViewModel.class);**可能会报错,这是因为依赖版本不对的原因

    解决方法:在build.grade中添加一条依赖

    dependencies {
           
           
     	implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    }
    
  3. 效果

    此时就算旋转ViewText中的数值也不会改变了。


LiveData

LiveData 是一个可以感知 Activity 、Fragment生命周期的数据容器。当 LiveData 所持有的数据改变时,它会通知相应的界面代码进行更新。同时,LiveData 持有界面代码 Lifecycle 的引用,这意味着它会在界面代码(LifecycleOwner)的生命周期处于 started 或 resumed 时作出相应更新,而在 LifecycleOwner 被销毁时停止更新。

主要作用在两点:

  • 数据存储器类。也就是一个用来存储数据的类。
  • 可观察。这个数据存储类是可以观察的,也就是比一般的数据存储类多了这么一个功能,对于数据的变动能进行响应。

主要思想就是用到了观察者模式思想,让观察者和被观察者解耦,同时还能感知到数据的变化(其实就是通过setValue()进行感知),所以一般被用到ViewModel中,ViewModel负责触发数据的更新,更新会通知到LiveData,然后LiveData再通知活跃状态的观察者

  1. ViewModelLiveData

    public class ViewModelLiveData extends ViewModel {
          
          
    
        private MutableLiveData<Integer> likeNumber;
    
        public MutableLiveData<Integer> getLikeNumber() {
          
          
            if(likeNumber == null) {
          
          
                likeNumber = new MutableLiveData<>();
                likeNumber.setValue(0);
            }
            return likeNumber;
        }
    
        public void addLikeNumber(Integer number){
          
          
            likeNumber.setValue(likeNumber.getValue() + number);
        }
    }
    
  2. MainActivity

    public class MainActivity extends AppCompatActivity {
          
          
    
        TextView textView;
        ImageButton imageButton1;
        ImageButton imageButton2;
        ViewModelLiveData viewModelLiveData;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            textView = findViewById(R.id.textView);
            imageButton1 = findViewById(R.id.imageButton1);
            imageButton2 = findViewById(R.id.imageButton2);
    
            viewModelLiveData = new ViewModelProvider(this).get(ViewModelLiveData.class);
    
            //相当于一个观察者,当数据发生改变时,会自动的对textView进行一次刷新
            //其他地方就不会出现对textView的修改了,进一步增加了代码的独立性77
            viewModelLiveData.getLikeNumber().observe(this,integer -> {
          
          
                textView.setText(String.valueOf(integer));
            });
    
            //+1
            imageButton1.setOnClickListener(view->{
          
          
                viewModelLiveData.addLikeNumber(1);
            });
    
            //-1
            imageButton2.setOnClickListener(view->{
          
          
                viewModelLiveData.addLikeNumber(-1);
            });
        }
    }
    
    1. 效果


DataBinding

什么是 DataBinding 呢,简单说来就是帮我们实现 view 和 data 绑定的工具,把数据映射到 view 的 xml中,可以在 xml 布局文件中实现 view 的赋值,方法调用。使用 DataBinding 后,我们不同再写 findViewById,不用再获取控件对象,不用再设置监听,可以节省我们 activity 中的很多获取控件,赋值,添加监听所需要的代码。

DataBinding 是个好东西,15年 google IO 大会就开始推了,最直接的变化就是催生了 android 中 MVVM 的出现,MVVM = MVP + DataBinding 。

DataBinding可以帮我们减少很多没必要的代码,大大提高我们的开发效率。比如大量减少使用findViewById()、setText(),setVisibility(),setEnabled()等代码的几率。

DataBinding主要解决了两个问题:

  • 需要多次使用findViewById等无营养的代码,损害了应用性能且令人厌烦
  • 更新UI数据需切换至UI线程,将数据分解映射到各个view比较麻烦

  1. 修改配置

    android {
          
          
        compileSdkVersion 30
        buildToolsVersion "30.0.2"
    
        defaultConfig {
          
          
            dataBinding {
          
          
                enabled true
            }
        }
    }
    

    上面写法已经过时,写下面这种写法

    android {
          
          
        buildFeatures {
          
          
            dataBinding = true
        }
    }
    
  2. 转换为databing形式的layout

    然后会自动帮我们创建一个ActivityMainBinding

  3. 创建ViewModel

    public class MyViewModel extends ViewModel {
          
          
    
        private MutableLiveData<Integer> likeNumber;
    
        public MutableLiveData<Integer> getLikeNumber() {
          
          
            if(likeNumber == null) {
          
          
                likeNumber = new MutableLiveData<>();
                likeNumber.setValue(0);
            }
            return likeNumber;
        }
    
        public void add(){
          
          
            likeNumber.setValue(likeNumber.getValue() + 1);
        }
    }
    
  4. MainActivity(进行一个绑定)

    public class MainActivity extends AppCompatActivity {
          
          
    
        MyViewModel myViewModel;
        ActivityMainBinding binding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            //setContentView(R.layout.activity_main);
            binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
    
            myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
            binding.setData(myViewModel);
            binding.setLifecycleOwner(this);
        }
    }
    
  5. 在view中设置好变量,并进行属性和函数调用,我们调用属性其实本质上调用的是get()方法。

    <data>
        <variable
              name="data"
              type="com.example.databinding.MyViewModel" />
    </data>
    
    <TextView
              android:id="@+id/textView"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@{String.valueOf(data.likeNumber)}"
              android:textSize="36sp"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintRight_toRightOf="parent"
              app:layout_constraintTop_toTopOf="parent"
              app:layout_constraintVertical_bias="0.251" />
    
    <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="384dp"
            android:text="@string/button"
            android:onClick="@{()->data.add()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    

小案例(篮球积分器)

  1. 创建一个项目,并修改配置

    plugins {
          
          
        id 'com.android.application'
    }
    
    android {
          
          
        compileSdkVersion 30
        buildToolsVersion "30.0.2"
    
        defaultConfig {
          
          
            applicationId "com.example.score"
            minSdkVersion 30
            targetSdkVersion 30
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildFeatures {
          
          
            dataBinding = true
        }
    
        buildTypes {
          
          
            release {
          
          
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
          
          
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    
    dependencies {
          
          
        implementation 'androidx.appcompat:appcompat:1.2.0'
        implementation 'com.google.android.material:material:1.2.1'
        implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
        testImplementation 'junit:junit:4.+'
        androidTestImplementation 'androidx.test.ext:junit:1.1.2'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
        implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    }
    
  2. 创建视图

  3. 创建ViewModel

    public class MyViewModel extends ViewModel {
          
          
    
        private MutableLiveData<Integer> aTeamScore;
        private MutableLiveData<Integer> bTeamScore;
        /**
        /* 存储回退数值
        */
        private Integer aBack,bBack;
    
        public MutableLiveData<Integer> getATeamScore() {
          
          
            if(aTeamScore == null){
          
          
                aTeamScore = new MutableLiveData<>();
                aTeamScore.setValue(0);
            }
            return aTeamScore;
        }
    
        public MutableLiveData<Integer> getBTeamScore() {
          
          
            if(bTeamScore == null){
          
          
                bTeamScore = new MutableLiveData<>();
                bTeamScore.setValue(0);
            }
            return bTeamScore;
        }
    
        public void aTeamAdd(int p){
          
          
            aBack = aTeamScore.getValue();
            bBack = bTeamScore.getValue();
            aTeamScore.setValue(aTeamScore.getValue()+p);
        }
    
        public void bTeamAdd(int p){
          
          
            aBack = aTeamScore.getValue();
            bBack = bTeamScore.getValue();
            bTeamScore.setValue(bTeamScore.getValue()+p);
        }
    
        /**
        * @Description 重置
        * @date 2020/11/12 11:10
        * @return
        */
        public void reset(){
          
          
            aTeamScore.setValue(0);
            bTeamScore.setValue(0);
        }
    
        /**
        * @Description 撤销操作
        * @date 2020/11/12 11:09
        * @return
        */
        public void undo(){
          
          
            aTeamScore.setValue(aBack);
            bTeamScore.setValue(bBack);
        }
    }
    
  4. 使用DataBinding,并调用ViewModel中的属性和方法

  5. MainActivity

    public class MainActivity extends AppCompatActivity {
          
          
    
        MyViewModel myViewModel;
        ActivityMainBinding binding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            //setContentView(R.layout.activity_main);
            binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
            myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
    
            binding.setData(myViewModel);
            binding.setLifecycleOwner(this);
        }
    }
    
  6. 之后创建一个横版的,并修改样式

  7. 演示


ViewModelSavedState

在上面的例子中,我们的数据存在ViewModel中,理论上是不会被清除的,相比于onSaveInstanceState确实方便了不少,但如果我们的进程被后台系统杀死,数据就会丢失

我们这里来检验一下(因为之前的本地化多语言,我将虚拟机切换成立了中文)。

  1. 打开开发者模式:设置->关于模拟设备->版本号(连续点击进入开发者模式)

  2. 设置不保留活动:**设置->系统->开发者选项->下滑到 ‘应用’ 栏->打开 ‘不保留活动’ 选项 或者 选择后台进程限制的不允许后台进程 **

  3. 进行测试

解决办法

  • onSaveInstanceState(太旧了)
  • viewModelSavedState

onSaveInstanceState方法

public class MainActivity extends AppCompatActivity {
    
    

    MyViewModel myViewModel;
    ActivityMainBinding binding;
    private static  final String KEY_A_NUMBER = "A_number";
    private static  final String KEY_B_NUMBER = "B_number";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        myViewModel = new ViewModelProvider(this).get(MyViewModel.class);

        if(savedInstanceState!=null){
    
    
            myViewModel.getATeamScore().setValue((Integer) savedInstanceState.get(KEY_A_NUMBER));
            myViewModel.getBTeamScore().setValue((Integer) savedInstanceState.get(KEY_B_NUMBER));
        }

        binding.setData(myViewModel);
        binding.setLifecycleOwner(this);

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
    
    
        super.onSaveInstanceState(outState);
        outState.putInt(KEY_A_NUMBER, myViewModel.getATeamScore().getValue());
        outState.putInt(KEY_B_NUMBER, myViewModel.getBTeamScore().getValue());
    }
}

viewModelSavedState方法

  1. 添加依赖

    implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
    
  2. 修改ViewModel

    public class MyViewModel extends ViewModel {
          
          
    
        //private MutableLiveData<Integer> aTeamScore;
        //private MutableLiveData<Integer> bTeamScore;
        private Integer aBack,bBack;
    
        private SavedStateHandle handle;
    
        private static  final String KEY_A_NUMBER = "A_number";
        private static  final String KEY_B_NUMBER = "B_number";
    
        public MyViewModel(SavedStateHandle handle) {
          
          
            this.handle = handle;
        }
    
        public MutableLiveData<Integer> getATeamScore() {
          
          
            if(!handle.contains(KEY_A_NUMBER)){
          
          
                handle.set(KEY_A_NUMBER,0);
            }
            return handle.getLiveData(KEY_A_NUMBER);
        }
    
        public MutableLiveData<Integer> getBTeamScore() {
          
          
            if(!handle.contains(KEY_B_NUMBER)){
          
          
                handle.set(KEY_B_NUMBER,0);
            }
            return handle.getLiveData(KEY_B_NUMBER);
        }
    
        public void aTeamAdd(int p){
          
          
            aBack = (Integer) handle.getLiveData(KEY_A_NUMBER).getValue();
            bBack = (Integer) handle.getLiveData(KEY_B_NUMBER).getValue();
            handle.set(KEY_A_NUMBER,aBack+p);
        }
    
        public void bTeamAdd(int p){
          
          
            aBack = (Integer) handle.getLiveData(KEY_A_NUMBER).getValue();
            bBack = (Integer) handle.getLiveData(KEY_B_NUMBER).getValue();
            handle.set(KEY_B_NUMBER,bBack+p);
        }
    
        /**
        * @Description 重置
        * @date 2020/11/12 11:10
        * @return
        */
        public void reset(){
          
          
            handle.set(KEY_A_NUMBER,0);
            handle.set(KEY_B_NUMBER,0);
        }
    
        /**
        * @Description 撤销操作
        * @date 2020/11/12 11:09
        * @return
        */
        public void undo(){
          
          
            handle.set(KEY_A_NUMBER,aBack);
            handle.set(KEY_B_NUMBER,bBack);
        }
    }
    
  3. 修改MainActivity

    public class MainActivity extends AppCompatActivity {
          
          
    
        MyViewModel myViewModel;
        ActivityMainBinding binding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          
          
            super.onCreate(savedInstanceState);
            //setContentView(R.layout.activity_main);
            binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
            myViewModel = new ViewModelProvider(this,new SavedStateViewModelFactory(getApplication(),this)).get(MyViewModel.class);
    
            binding.setData(myViewModel);
            binding.setLifecycleOwner(this);
    
        }
    }
    

SharedPreferences

通过上面的ViewModelSavedState,我们进入后台后数据也不会丢失了,但是当我们点击返回时,数据还会丢失。

解决办法:SharedPreferences,永久保存数据

简单使用

public class MainActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SharedPreferences shp = getPreferences(Context.MODE_PRIVATE);
        
        //存储数据
        SharedPreferences.Editor edit = shp.edit();
        edit.putInt("NUMBER", 100);
        edit.commit();
        
        //读取
        int x = shp.getInt("NUMBER", 0);
        Log.d("myLog", "onCreate:"+x);
    }
}

运行代码,控制台日志打印如下

然后找到右下角的

点击,会看到一个目录,进入到data/data/,你会看到很多的包名,然后找到你当前MainActivity所在的包名,单击右键,进行一次刷新

其中的数据如下

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <int name="NUMBER" value="100" />
</map>

自定义文件名

public class MainActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //SharedPreferences shp = getPreferences(Context.MODE_PRIVATE);
        SharedPreferences shp = getSharedPreferences("My_DATA", Context.MODE_PRIVATE);

        //存储数据
        SharedPreferences.Editor edit = shp.edit();
        edit.putInt("NUMBER", 600);
        edit.commit();

        //读取
        int x = shp.getInt("NUMBER", 0);
        Log.d("myLog", "onCreate:"+x);
    }
}

运行


类结构

我们当前的类继承自ContextWrapper类,getSharedPreferences方法是在ContextWrapper类中定义的。


定义Model

public class MyData {
    
    

    private int data;

    private Context context;
    private Resources resources;

    private SharedPreferences shp;

    /**
    * @Description 初始化基本信息,必须传入context对象
    * @date 2020/11/14 14:56
    * @param context
    * @return
    */
    public MyData(Context context) {
    
    
        this.context = context;
        this.resources = context.getResources();
        shp = context.getSharedPreferences(resources.getString(R.string.MY_DATA),Context.MODE_PRIVATE);
    }

    /**
    * @Description 存储数据
    * @date 2020/11/14 14:55
    * @return
    */
    public void save(){
    
    
        SharedPreferences.Editor edit = shp.edit();
        edit.putInt(resources.getString(R.string.MY_KEY), data);
        edit.commit();
    }

    /**
    * @Description 读取数据
    * @date 2020/11/14 14:55
    * @return
    */
    public int load(){
    
    
        data = shp.getInt(resources.getString(R.string.MY_KEY), resources.getInteger(R.integer.defValue));
        return data;
    }

    public int getData() {
    
    
        return data;
    }

    public void setData(int data) {
    
    
        this.data = data;
    }
}

其中使用到的常量放在了资源中,自己创建一个int资源

-----string.xml-----
<resources>
    <string name="app_name">SharedPreferences</string>
    <string name="MY_DATA">my_data</string>
    <string name="MY_KEY">my_key</string>
</resources>

-----int.xml-----
<resources>
    <integer name="defValue">0</integer>
</resources>

在MainActivity中可以定义一个MyData,并传入context

MyData myData = new MyData(this);

这样子传可以,但不好,因为可能会引起内存的泄露。因为我们的Activity在翻转,切换等情况会进行重新创建,而我们的myData中又有一个引用指向Activity,就会导致当前Activity对象并不会被垃圾回收器回收。

应该传递Application,只要应用还存在,就不会被重新创建。

MyData myData = new MyData(getApplication());

MainActivity代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MyData myData = new MyData(getApplication());
    myData.setData(800);
    myData.save();

    Log.d("myLog", "onCreate:"+myData.load());
}

之后自己可以查看结果


AndroidViewModel和小案例

首先,修改配置build.gradle,导入依赖

buildFeatures {
    
    
    dataBinding = true
}

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'

做个界面

编写viewModel

package com.example.viewmodelshp;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.SavedStateHandle;

/**
 * @author codekiller
 * @date 2020/11/14 15:19
 * @Description ViewModel
 */
public class MyViewModel extends AndroidViewModel {
    
    

    private SavedStateHandle handle;

    private String key = getApplication().getString(R.string.data_key);
    private String shpName = getApplication().getString(R.string.shp_name);

    public MyViewModel(@NonNull Application application, SavedStateHandle savedStateHandle) {
    
    
        super(application);
        this.handle = savedStateHandle;

        if (!this.handle.contains(key)) {
    
    
            load();
        }
    }

    public LiveData<Integer> getNumber() {
    
    
        return handle.getLiveData(key);
    }

    /**
     * @return
     * @Description 加载数据
     * @date 2020/11/14 15:41
     */
    public void load() {
    
    
        SharedPreferences shp = getApplication().getSharedPreferences(shpName, Context.MODE_PRIVATE);
        handle.set(key, shp.getInt(key, 0));
    }

    /**
     * @return
     * @Description 保存数据
     * @date 2020/11/14 15:41
     */
    public void save() {
    
    
        SharedPreferences shp = getApplication().getSharedPreferences(shpName, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = shp.edit();
        edit.putInt(key, getNumber().getValue());
        edit.commit();
    }

    /**
     * @param x
     * @return
     * @Description 进行+和-运算
     * @date 2020/11/14 15:39
     */
    public void add(int x) {
    
    
        handle.set(key, getNumber().getValue() + x);
        //save(); 耗时间
    }

}

常量资源

<resources>
    <string name="app_name">ViewModelSHP</string>
    <string name="button_plus">+</string>
    <string name="button_minus">-</string>
    <string name="textview">HelloWorld</string>
    <string name="data_key">DATA_KEY</string>
    <string name="shp_name">shp_name</string>
</resources>

修改activity_main.xml,先转化为data binding layout,再修改代码(这里给出了修改的部分)

<data>
    <variable
            name="data"
            type="com.example.viewmodelshp.MyViewModel" />
</data>

<TextView
	android:text="@{String.valueOf(data.getNumber())}"/>

<Button
        android:onClick="@{()->data.add(1)}"/>

<Button
        android:onClick="@{()->data.add(-1)}"/>

修改MainActivity

public class MainActivity extends AppCompatActivity {
    
    

    MyViewModel myViewModel;
    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        myViewModel = new ViewModelProvider(this, new SavedStateViewModelFactory(getApplication(), this)).get(MyViewModel.class);
        binding.setData(myViewModel);
        binding.setLifecycleOwner(this);
    }

    @Override
    protected void onPause() {
    
    
        super.onPause();
        //保存数据
        myViewModel.save();
    }
}

之后,不论是进程杀死,还是退出应用,关机,数据都不会丢失。但是如果你手机没电了突然关机,onPause()调用不了,数据依然会丢失。


猜你喜欢

转载自blog.csdn.net/qq_44766883/article/details/112919888