【16课】Android Studio 之 【数据存储与还原的总结】AndroidViewModel+SharedPreferences+LiveData
Posted on 2019-11-02 11:28 孤峰皓月 阅读(2028) 评论(0) 编辑 收藏 举报SharedPreferences+LiveData结合的方式,会比较好,重启数据会保存操作记录!
LiveData:能够自动监听更新界面上的控件!
SharedPreferences:数据永久化保存,保存在硬件上(只能保存简单的数据:如字符串、布尔值、数值型等等)
AndroidViewModel:可以直接在这个类里面访问context或getApplication()
SavedStateHandle:存储的生命周期比较长,但是如果重启系统或应用被杀死,数据会丢失。
ViewModel中通过SharedPreferences保存到硬件上的数据,会比较耗性能
可以放在Activity后台中onpause()事件中
==========================================
AndroidViewModel是ViewModel的一个子类,可以直接调用getApplication(),由此可以访问应用的全局资源。
在 MyViewModel 这个类中,此类直接继承自 AndroidViewModel ,平时一般这个类是继承 ViewModel
public class MyViewModel extends AndroidViewModel {
然后在 MyViewModel 这个类中,可以直接用 getApplication()这个方法,访问全局资源文件了
getApplication().getResources().getString(R.string.shp_name);
通过 SavedStateHandle 与 LiveData 配合 自动更新控件数据
通过 SharedPreferences 对数据进行 持久化 存储!关机后再开机,之前数据状态还会显示
1. MyViewModel 类
package com.example.androidviewmodeltest; 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; public class MyViewModel extends AndroidViewModel { //方法1. 本类继承自 ViewModel public class MyViewModel extends ViewModel //通过 context 外部类,就可以直接对 SharedPreferences 进行访问 /*Context context; void test(){ //通过 context 外部类,就可以直接对 SharedPreferences 进行访问 context.getSharedPreferences("",Context.MODE_PRIVATE); }*/ //Application application; SavedStateHandle handle;//需要在 build.gradle中引用 implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha01' //这个类继承自AndroidViewModel 就可以直接访问: getApplication().getResources().getString(R.string.buttonJia);//这样就可以直接访问全局资源文件了 String key = getApplication().getResources().getString(R.string.dataKey); String shpName = getApplication().getResources().getString(R.string.shp_name); //方法2. 继续自 AndroidViewModel public class MyViewModel extends AndroidViewModel public MyViewModel(@NonNull Application application, SavedStateHandle handle) { super(application); //getApplication().getResources().getString(R.string.buttonJia);//这样就可以直接访问全局资源文件了 this.handle = handle; if(!handle.contains(key)) load(); } //public 整个项目均方法可见 //private 只能在本类中方法可见 //protected 本类或子类可见 //没有前缀,即不写的话,在本包中的类都可见, 例如在 MainActivity中访问load()这个方法 myViewModel.load(); public LiveData<Integer> getNumber(){ return handle.getLiveData(key); } void load(){ SharedPreferences shp = getApplication().getSharedPreferences(shpName,Context.MODE_PRIVATE); int x = shp.getInt(key,0); handle.set(key,x); } void save(){ SharedPreferences shp = getApplication().getSharedPreferences(shpName,Context.MODE_PRIVATE); SharedPreferences.Editor editor = shp.edit(); editor.putInt(key,getNumber().getValue()); editor.apply(); } public void add(int x){ handle.set(key,getNumber().getValue()+x); //save();//如果装饰save() 操作放这里,会频繁保存数据,可能会影响性能 } }
2. MainActivity 类
package com.example.androidviewmodeltest; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.databinding.DataBindingUtil; import androidx.lifecycle.SavedStateVMFactory; import androidx.lifecycle.ViewModelProviders; import com.example.androidviewmodeltest.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { MyViewModel myViewModel; ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); // myViewModel.application = getApplication(); // myViewModel.context = getApplicationContext(); //context是比较顶层的类, binding = DataBindingUtil.setContentView(this,R.layout.activity_main); myViewModel = ViewModelProviders.of(this,new SavedStateVMFactory(this)).get(MyViewModel.class); binding.setData(myViewModel); binding.setLifecycleOwner(this); } //在 onPause 事件中操作保存,性能比较好,不频繁操作保存记录 //但是如果手机突然没电或重启,可能会导致此方法没调用成功 @Override protected void onPause() { super.onPause(); myViewModel.save(); } }