ViewModel 的已保存状态模块   Android Jetpack 的一部分。

保存界面状态这篇文章提到过,ViewModel 对象可以处理配置更改,因此您无需担心旋转时或其他情况下的状态。但是,如果您需要处理系统发起的进程终止,则可以使用 onSaveInstanceState() 作为备用方式。

界面状态通常在 ViewModel 对象中(而不是 Activity 中)存储或引用;因此,使用 onSaveInstanceState() 时需要该模块可以为您处理的某个样板。

模块设置好以后,ViewModel 对象会通过其构造函数接收 SavedStateHandle 对象。这是一个键值对映射,用于向已保存状态写入对象以及从其中检索对象。这些值会在进程被系统终止后继续保留,并通过同一对象保持可用状态。

设置和使用

使用 Fragment 1.2.0 或其传递依赖项 Activity 1.1.0 时,ViewModel 实例的默认出厂设置支持在无任何其他配置的情况下将适当的 SavedStateHandle 传递到您的 ViewModel

Kotlin

    // Use the Kotlin property extension in the fragment-ktx / activity-ktx artifacts
    val vm: SavedStateViewModel by viewModels()

    

Java

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

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

Kotlin

    class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() { ... }
    

Java


    public class SavedStateViewModel extends ViewModel {
        private SavedStateHandle mState;

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

提供自定义 ViewModelProvider.Factory 实例时,您可以通过扩展 AbstractSavedStateViewModelFactory 启用 SavedStateHandle

存储和检索值

SavedStateHandle 类包含键值对映射应有的方法:

  • get(String key)
  • contains(String key)
  • remove(String key)
  • set(String key, T value)
  • keys()

此外,还有一种特殊的方法:getLiveData(String key),用于返回封装在 LiveData 可观察对象中的值。

可接受的类

类型/类 数组支持
double double[]
int int[]
long long[]
String String[]
byte byte[]
char char[]
CharSequence CharSequence[]
float float[]
Parcelable Parcelable[]
Serializable Serializable[]
short short[]
SparseArray
Binder
Bundle
ArrayList
Size (only in API 21+)
SizeF (only in API 21+)

其他资源

如需详细了解 ViewModel 的已保存状态模块,请参阅以下资源。

Codelab