ViewModel 基本使用
LiveData 基本使用
DataBinding 基本使用
注:请在学习以上内容之后查看:
问题补充:
按照上述内容中那样操作,会出现这样的问题,如果此时系统杀死后台进程,ViewModel 会重新创建,之前的 UI 数据丢失,Activity 上的数据也被重置。如下图:
为了解决这个问题,可以使用 SaveStateHandle,官方文档:
SavedStateHandle 类是一个键值对映射,用于通过 set() 和 get() 方法向已保存的状态写入数据以及从中检索数据。此外,您还可以从封装在 LiveData(可使用 getLiveData() 查看)中的 SavedStateHandle 检索值。通过使用 SavedStateHandle,查询值会在进程终止后保留下来,从而确保用户在重新创建前后看到同一组过滤后的数据,而无需 Activity 或 Fragment 手动保存、恢复该值并将其重新转给 ViewModel。
此外,SavedStateHandle 还包含其他您与键值对映射互动时可能会用到的方法:
- contains(String key) - 检查是否存在给定键的值。
- remove(String key) - 移除给定键的值。
- keys() - 返回 SavedStateHandle 中包含的所有键。
如何使用:
- 首先添加依赖:
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.1'
- 修改 MyViewModel
public class MyViewModel extends ViewModel {
private SavedStateHandle handle;
public MyViewModel(SavedStateHandle handle) {
this.handle = handle;
}
public MutableLiveData getLikedNumber() {
if (!handle.contains("number")){
handle.set("number", 0);
}
MutableLiveData likedNumber = handle.getLiveData("number");
return likedNumber;
}
public void addNumber(int n) {
getLikedNumber().setValue(getLikedNumber().getValue()+n);
}
}
修改之后,在使用 SaveStateHandle 后,ViewModel 不会在杀死后台进程之后重新创建,因为 ViewModel 的存活周期跨过了系统杀死进程的操作。如下图:
当我们按下 back 键、退出程序、关机后,系统重新启动,使用上述方法,ViewModel 仍然会重新创建,数据也会重置。那么怎么解决呢?
使用 SharePreference 实现数据永久性保存
使用步骤:
1. 修改 ViewModel 使其继承 AndroidViewModel:
public class MyViewModel extends AndroidViewModel {
private SavedStateHandle handle;
private String key = getApplication().
getResources().getString(R.string.data_key);
private String shpName = getApplication().
getResources().getString(R.string.shp_name);
private SharedPreferences shp;
public MyViewModel(@NonNull Application application, SavedStateHandle handle) {
super(application);
this.handle = handle;
if (!handle.contains(key)) {
load();// 获取数据
}
}
public LiveData getLikedNumber() {
LiveData likedNumber = handle.getLiveData(key);
return likedNumber;
}
private void load() {
shp = getApplication().
getSharedPreferences(shpName, Context.MODE_PRIVATE);
int number = shp.getInt(key, 0);
handle.set(key, number);
}
public void save() {
SharedPreferences.Editor edit = shp.edit();
edit.putInt(key, getLikedNumber().getValue());
edit.apply();
}
public void addNumber(int n) {
handle.set(key, getLikedNumber().getValue() + n);
}
}
2.保存数据
一种方式是在 Activity 中重写 onPause() 方法,在 Activity 每次停止之后保存,调用次数少,但是也存在弊端,当app在使用途中,手机突然关机,此时 Activity 是不执行 onPause() 方法的,数据并没有得到保存。
@Override
protected void onPause() {
super.onPause();
viewModel.save();
}
另一种方式是在 ViewModel 的 addNumber() 方法中调用,每次更新值都调用一次 save()方法,这种方式可以保证数据一定被保存,但是当我们多次更新值会频繁调用 save()方法,这会导致程序运行速度降低。
public void addNumber(int n) {
handle.set(key, getLikedNumber().getValue() + n);
save();
}



