如何转换 ViewModel 以利用状态保存?

Posted

技术标签:

【中文标题】如何转换 ViewModel 以利用状态保存?【英文标题】:How to convert ViewModel to utilize state saving? 【发布时间】:2020-09-20 12:03:18 【问题描述】:

我有一个ViewModel,我目前正在使用它来包含数据并在片段之间共享值。此模型还有助于在活动开始时为应用实例化数据。

我现在正尝试在我的应用程序中添加状态保存功能,但我对如何将两个系统合并在一起感到困惑。 android 文档提到使用这个构造函数:

public MyViewModel(SavedStateHandle savedStateHandle) 
    mState = savedStateHandle;

但是,我不确定状态是如何传递的,以及这个构造函数是如何在活动中使用的(这是我的用法):

 myViewModel = new ViewModelProvider(requireActivity()).get(myViewModel.class);

无论如何,由于我还需要实例化数据以防 saveState 为空,所以我不确定该部分如何适应。作为参考,这里是我的 ViewModel 类的概要:

public class myViewModel extends ViewModel 
//    private MutableLiveData<Integer> foo;  <-- obsolete with state saving

    private SavedStateHandle mState;
    private static final String FOO_KEY = "foo";

    // Do I need this anymore? How do I combine this with the other constructor?
    public myViewModel() 
        foo = new MutableLiveData<>();
        foo.setValue(4);
    

    // Constructor for the savedStateHandle
    public myViewModel(SavedStateHandle savedStateHandle)  mState = savedStateHandle; 

    LiveData<Integer> getFoo()  return mState.getLiveData(FOO_KEY); 

    void setFoo(int foo)  mState.set(FOO_KEY, foo); 


显然,如果我取出旧的构造函数和MutableLiveData 成员,那么当我访问片段中的 ViewModel 时,数据将为空(因为我还没有告诉活动显式保存状态),并且我还没有实例化任何数据。

【问题讨论】:

【参考方案1】:

你不需要你的无参数构造函数。相反,您应该使用带有初始值的 other getLiveData() method:

public class myViewModel extends ViewModel 

    private SavedStateHandle mState;
    private static final String FOO_KEY = "foo";

    public myViewModel(SavedStateHandle savedStateHandle) 
        mState = savedStateHandle;
    

    LiveData<Integer> getFoo() 
        // Get the LiveData, setting the default value if it doesn't
        // already have a value set.
        return mState.getLiveData(FOO_KEY, 4);
    

    void setFoo(int foo)  mState.set(FOO_KEY, foo); 


【讨论】:

这看起来很有希望,我今天会试一试 感谢您的出色回答,这正是我所需要的。我将此与逻辑检查相结合,以确保密钥是否已填充:if (!savedState.contains(MY_KEY) return getLiveData(MY_KEY, defaultValue) @MatthewStrom - 您不需要这样做 - getLiveData 会为您执行此操作,仅在尚未设置值时应用默认值。

以上是关于如何转换 ViewModel 以利用状态保存?的主要内容,如果未能解决你的问题,请参考以下文章

使用 onSaveInstanceState() 和 ViewModel 保存活动的状态

Android - MVVM中ViewModel状态的最佳实践?

如何创建可以保存状态的不可为空的 LiveData

Android JetPack组件之ViewModel状态的保存(程序在后台被系统杀死数据也存活)

从第二个片段访问时 ViewModel 数据丢失状态

Android Studio 之 ViewModel (转)