2.24 AndroidViewModel 让ViewModel 访问全局资源

Posted 半暖时光丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.24 AndroidViewModel 让ViewModel 访问全局资源相关的知识,希望对你有一定的参考价值。

本次的示例是一个简单的加减法程序:

 当程序被关闭后,在开启之后会读取之前的数据,载入程序当中。数据不会丢失(主要使用androidViewModel)

AndroidViewModel 是ViewModel的一个子类,可以直接调用getApplication(),由此来访问应用的全局资源

 

public class MyViewModel extends AndroidViewModel {   直接继承自AndroidViewModel
然后在 MyViewModel 这个类中,可以直接用 getApplication()这个方法,访问全局资源文件

方法:

getApplication().getResources().getString(R.string.XXX);
通过 SavedStateHandle 与 LiveData 配合 自动更新控件数据
通过 SharedPreferences 对数据进行 持久化 存储!关机后再开机,之前数据状态还会显示

 

程序代码如下:

 

MyViewModel.java 

 

 1 package com.example.viewmodelshp;
 2 
 3 import android.app.Application;
 4 import android.content.Context;
 5 import android.content.SharedPreferences;
 6 
 7 import androidx.annotation.NonNull;
 8 import androidx.lifecycle.AndroidViewModel;
 9 import androidx.lifecycle.LiveData;
10 import androidx.lifecycle.SavedStateHandle;
11 
12 @SuppressWarnings("ConstantConditions")
13 public class MyViewModel extends AndroidViewModel {  //继承Android 的 ViewModel  可直接访问getApplication
14     private SavedStateHandle handle;
15     private String key = getApplication().getResources().getString(R.string.data_key);
16     private String shpname = getApplication().getResources().getString(R.string.shp_name);
17 
18     public MyViewModel(@NonNull Application application, SavedStateHandle handle) {
19         super(application);
20         this.handle = handle;
21         if (!handle.contains(key)) {
22             load();
23         }
24     }
25 
26     public LiveData<Integer> getNumber() {
27         return handle.getLiveData(key);
28     }
29 
30     //读取操作
31     private void load() {
32         SharedPreferences shp = getApplication().getSharedPreferences(shpname, Context.MODE_PRIVATE);
33         int x = shp.getInt(key, 0);
34         handle.set(key, x);
35     }
36 
37     void save() {
38         SharedPreferences shp = getApplication().getSharedPreferences(shpname, Context.MODE_PRIVATE);
39         SharedPreferences.Editor editor = shp.edit();
40         editor.putInt(key, getNumber().getValue() == null ? 0 : getNumber().getValue());
41         editor.apply();
42     }
43 
44     public void add(int x) {
45         handle.set(key, getNumber().getValue() == null ? 0 : getNumber().getValue() + x);
46         //保存操作 当程序被杀死也会从新读取 不会频繁变动 比较好 频繁则消耗时间
47         //save();
48     }
49 
50 
51     // Application  application;
52     //  Context context;
53 }

 

 

MainActivity.java

 1 package com.example.viewmodelshp;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 import androidx.databinding.DataBindingUtil;
 5 import androidx.lifecycle.SavedStateVMFactory;
 6 import androidx.lifecycle.ViewModelProviders;
 7 import androidx.lifecycle.ViewModelProviders;
 8 import android.os.Bundle;
 9 import com.example.viewmodelshp.databinding.ActivityMainBinding;
10 
11 public class MainActivity extends AppCompatActivity {
12     MyViewModel myViewModel;
13     ActivityMainBinding binding;
14 
15     @Override
16     protected void onCreate(Bundle savedInstanceState) {
17         super.onCreate(savedInstanceState);
18         setContentView(R.layout.activity_main);
19       //  myViewModel.application = getApplication();
20       //  myViewModel.context =getApplicationContext();
21         binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
22         myViewModel= ViewModelProviders.of(this,new SavedStateVMFactory(this)).get(MyViewModel.class);
23       //  myViewModel= new ViewModelProvider(this,new SavedStateViewModelFactory(this)).get(MyViewModel.class);
24         binding.setData(myViewModel);
25         binding.setLifecycleOwner(this);
26     }
27 
28     @Override
29     protected void onPause() {
30         super.onPause();
31         //存储   数据可靠 不会频繁操作  但是如果手机突然死机或者没电会丢失数据
32 myViewModel.save(); 33 } 34 35 //不一定会被呼叫 还有 ondestory 36 @Override 37 protected void onStop() { 38 super.onStop(); 39 } 40 }

 

代码注释找到了一个比较好前辈学习,认识到自学有很多的不足:

https://www.cnblogs.com/gfwei/p/11781166.html

 

 

在视频中根据规范要求,将各个组件的名称命名如下:

1 <resources>
2     <string name="app_name">ViewModelSHP</string>
3     <string name="button_plus"> + </string>
4     <string name="button_minus"> - </string>
5     <string name="data_key">DATA_KEY</string>
6     <string name="shp_name">SHP_NAME</string>
7 </resources>

 

databing 类型的xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools">
 5 
 6     <data>
 7         <variable
 8             name="data"
 9             type="com.example.viewmodelshp.MyViewModel" />
10     </data>
11 
12     <!--  variable data 自定义的变量,type 是它的类型   -->
13 
14 
15     <androidx.constraintlayout.widget.ConstraintLayout
16         android:layout_width="match_parent"
17         android:layout_height="match_parent"
18         tools:context=".MainActivity">
19 
20         <Button
21             android:id="@+id/button2"
22             android:layout_width="wrap_content"
23             android:layout_height="wrap_content"
24             android:onClick="@{()->data.add(-1)}"
25             android:text="@string/button_minus"
26             app:layout_constraintBottom_toBottomOf="parent"
27             app:layout_constraintEnd_toEndOf="parent"
28             app:layout_constraintHorizontal_bias="0.761"
29             app:layout_constraintStart_toStartOf="parent"
30             app:layout_constraintTop_toTopOf="parent"
31             app:layout_constraintVertical_bias="0.477" />
32         <!-- {()->data.add(-1)} 调用一个函数的格式  -->
33 
34         <TextView
35             android:id="@+id/textView"
36             android:layout_width="wrap_content"
37             android:layout_height="wrap_content"
38             android:text="@{String.valueOf(data.getNumber)}"
39             android:textSize="30sp"
40             app:layout_constraintBottom_toBottomOf="parent"
41             app:layout_constraintLeft_toLeftOf="parent"
42             app:layout_constraintRight_toRightOf="parent"
43             app:layout_constraintTop_toTopOf="parent"
44             app:layout_constraintVertical_bias="0.3"
45             tools:text="100" />
46 
47         <Button
48             android:id="@+id/button"
49             android:layout_width="wrap_content"
50             android:layout_height="wrap_content"
51             android:onClick="@{()->data.add(1)}"
52             android:text="@string/button_plus"
53             app:layout_constraintBottom_toBottomOf="parent"
54             app:layout_constraintEnd_toEndOf="parent"
55             app:layout_constraintHorizontal_bias="0.244"
56             app:layout_constraintStart_toStartOf="parent"
57             app:layout_constraintTop_toTopOf="parent"
58             app:layout_constraintVertical_bias="0.477" />
59 
60     </androidx.constraintlayout.widget.ConstraintLayout>
61 </layout>

 

以上是关于2.24 AndroidViewModel 让ViewModel 访问全局资源的主要内容,如果未能解决你的问题,请参考以下文章

Cannot create an instance of class AndroidViewModel (androidx ViewModelProvider AndroidViewModel)

创建 ViewModel 或 AndroidViewModel 的方法

安卓基础(AndroidViewModel)

无法创建 AndroidViewModel 子类的实例

如何为 AndroidViewModel 创建视图模型工厂?

AndroidViewModel+LiveData:更加直接地控制视图的方式