ViewModel SavedState 是 Jetpack ViewModel 组件的一部分,它允许 ViewModel 保存和恢复状态数据,即使在设备配置更改(如屏幕旋转)或进程被系统回收后重新创建时,也能保留和恢复 ViewModel 的状态。以下是 ViewModel SavedState 的工作原理及其基本使用方法。
ViewModel SavedState 原理
-
SavedStateHandle:
SavedStateHandle
是 ViewModel SavedState 的核心组件。它是一个键值对映射,用于保存和恢复状态数据。SavedStateHandle
可以在 ViewModel 中使用,用于保存需要持久化的数据。 -
SavedStateRegistry:
SavedStateRegistry
是一个接口,允许组件(如 Activity 和 Fragment)保存和恢复其状态。ViewModel 使用SavedStateRegistry
来管理SavedStateHandle
的数据。 -
自动保存和恢复:当配置更改或进程重启时,ViewModel 可以通过
SavedStateHandle
自动保存和恢复状态数据。系统会在适当的时间点保存数据,并在 ViewModel 重新创建时恢复数据。 -
集成 Lifecycle:ViewModel SavedState 与 Lifecycle 组件集成,确保在适当的生命周期事件中保存和恢复状态数据。
基本使用方法
-
添加依赖项:在项目的
build.gradle
文件中添加 ViewModel SavedState 的依赖项。dependencies { def lifecycle_version = "2.3.1" implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version" }
-
创建 ViewModel 并使用 SavedStateHandle:创建一个继承自
ViewModel
的类,并通过构造函数注入SavedStateHandle
。使用SavedStateHandle
保存和恢复状态数据。class MyViewModel(private val state: SavedStateHandle) : ViewModel() { companion object { private const val KEY_COUNTER = "counter" } val counter: LiveData<Int> = state.getLiveData(KEY_COUNTER, 0) fun incrementCounter() { val currentCounter = state.get<Int>(KEY_COUNTER) ?: 0 state.set(KEY_COUNTER, currentCounter + 1) } }
-
在 Activity 或 Fragment 中创建 ViewModel:使用
ViewModelProvider
创建 ViewModel,并确保使用SavedStateViewModelFactory
。class MyActivity : AppCompatActivity() { private lateinit var viewModel: MyViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewModel = ViewModelProvider(this, SavedStateViewModelFactory(application, this)) .get(MyViewModel::class.java) viewModel.counter.observe(this, Observer { counter -> // 更新 UI findViewById<TextView>(R.id.counter_text).text = counter.toString() }) findViewById<Button>(R.id.increment_button).setOnClickListener { viewModel.incrementCounter() } } }
ViewModel SavedState 工作流程
-
初始化 SavedStateHandle:当 ViewModel 被创建时,系统会通过
SavedStateViewModelFactory
创建一个SavedStateHandle
实例,并将其传递给 ViewModel。 -
保存状态数据:在 ViewModel 中使用
SavedStateHandle
保存需要持久化的数据。当配置更改(如屏幕旋转)或进程被系统回收时,系统会自动调用SavedStateHandle
保存数据。 -
恢复状态数据:当 ViewModel 重新创建时,系统会通过
SavedStateHandle
恢复之前保存的数据,并将其传递给新的 ViewModel 实例。 -
更新 UI:通过 LiveData 或其他观察者模式,将恢复的数据更新到 UI 上,确保用户界面与保存的状态一致。
ViewModel SavedState 的优势
- 持久化状态数据:即使在配置更改或进程被系统回收后,仍能保留和恢复 ViewModel 的状态数据,提供了更好的用户体验。
- 简化状态管理:使用
SavedStateHandle
简化了状态数据的保存和恢复,不需要手动管理 Bundle 或其他持久化机制。 - 集成 Lifecycle:与 Lifecycle 组件集成,确保状态数据在适当的生命周期事件中保存和恢复。
- 减少内存泄漏:与 Activity 或 Fragment 的生命周期无关,避免了因 Activity 或 Fragment 的重新创建导致的内存泄漏问题。
通过以上原理和使用方法,ViewModel SavedState 提供了一种高效、可靠的方式来管理和持久化 ViewModel 的状态数据,实现了状态数据的自动保存和恢复,提升了应用的稳定性和用户体验。