18

ViewModel如果以下列方式使用,新类的实例可以在配置更改后继续存在:

mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);

但是,除了配置更改之外,还有一个保存-恢复的场景,即整个应用程序的进程都被杀死了。

ViewModel在保存-恢复场景中会保留里面的字段值吗?


编辑:基于这个问题的答案,我写了这篇文章:Android ViewModel Architecture Component is Dangerous

4

2 回答 2

17

根据ViewModelProvider文档(检查get方法),ViewModel当应用程序的进程被杀死时不保留:

创建的 ViewModel 与给定的范围相关联,并且只要范围处于活动状态就会保留(例如,如果它是一个活动,直到它完成或进程被杀死)

另外检查 Ian Lake 对类似问题的回答: https ://medium.com/@ianhlake/you-are-correct-the-viewmodel-is-destroyed-if-your-process-is-killed-by-android-ef611fcd51e6

你是对的:如果你的进程被 Android 杀死,ViewModel 就会被破坏。就像以前一样,您应该使用 onSaveInstanceState() 来存储您以后必须以与以前相同的状态重新创建 Activity 的任何数据。

我还推荐阅读 Android ViewModel Architecture Component is Dangerous

于 2017-05-30T10:30:39.477 回答
5

谷歌现在似乎为此提供了一个解决方案

ViewModel 的已保存状态模块

UI State 通常存储或引用在 ViewModel 对象中,而不是活动中;因此使用 onSaveInstanceState() 需要该模块可以为您处理的一些样板文件。

设置模块后,ViewModel 对象通过其构造函数接收 SavedStateHandle 对象。这是一个键值映射,可让您在保存状态中写入和检索对象。这些值将在进程被系统终止后保持不变,并通过同一个对象保持可用。


设置

implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc02'(2019 年 11 月 7 日)


用法

为了设置 ViewModel 来接收 SavedStateHandle,您需要使用扩展 AbstractSavedStateVMFactory 的工厂来创建它们。

SavedStateViewModel vm = new ViewModelProvider(this, new SavedStateVMFactory(this))
        .get(SavedStateViewModel.class);

之后,您的 ViewModel 可以有一个接收 SavedStateHandle 的构造函数:


public class SavedStateViewModel extends ViewModel {
    private SavedStateHandle mState;

    public SavedStateViewModel(SavedStateHandle savedStateHandle) {
        mState = savedStateHandle;
    }
    ...
}

存储和检索值

SavedStateHandle类具有您期望的键值映射方法

  • 获取(字符串键)
  • 包含(字符串键)
  • 删除(字符串键)
  • 设置(字符串键,T值)
  • 键()
于 2019-11-12T14:36:30.900 回答