以下是关于 Android Jetpack 中 ViewModel 的全面解析,结合其核心作用、工作原理、使用方法和最佳实践,帮助你高效掌握这一核心组件。
🔄 一、ViewModel 的核心作用与设计目标
ViewModel 是 Jetpack 架构组件的核心部分,专为解决 Android 开发中 UI 数据管理的痛点而设计:
-
数据持久化
- 在配置更改(如屏幕旋转、语言切换)时保留数据,避免重复加载。
- 对比
onSaveInstanceState()
:支持存储复杂对象(如 LiveData),而非仅限简单数据类型。
-
生命周期感知
- 自动清理资源:当关联的 Activity/Fragment 永久销毁(非配置变更)时,触发
onCleared()
释放资源。 - 避免内存泄漏:绝不持有 Context 或 View 引用 ,需用应用上下文时继承
AndroidViewModel
。
- 自动清理资源:当关联的 Activity/Fragment 永久销毁(非配置变更)时,触发
-
关注点分离
- 剥离 UI 逻辑:Activity/Fragment 仅负责显示数据与交互,数据处理由 ViewModel 管理。
- 支持数据共享:多个 Fragment 可通过同一 Activity 作用域共享 ViewModel 实例。
⚙️ 二、ViewModel 的工作原理与生命周期特性
ViewModel 的生命周期与 **ViewModelStoreOwner
**(如 Activity/Fragment)绑定,关键机制如下:
-
生命周期范围 :从 Activity 的
onCreate()
到完全销毁(onDestroy()
),屏幕旋转时不被重建。 -
数据恢复流程:
graph LR A["Activity 重建"] --> B["ViewModelProvider 获取实例"] B --> C{"是否存在现有 ViewModel?"} C -->|"是"| D["复用原 ViewModel"] C -->|"否"| E["创建新 ViewModel"] -
与 LiveData 协同 :
LiveData 自动感知 UI 状态,仅在活跃生命周期中更新 UI,避免无效回调。
🛠️ 三、ViewModel 的基本使用
1. 添加依赖
arduino
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" // Kotlin
implementation "androidx.lifecycle:lifecycle-viewmodel:2.6.2" // Java
}
2. 创建 ViewModel 类
kotlin
class CounterViewModel : ViewModel() {
private val _count = MutableLiveData(0)
val count: LiveData<Int> get() = _count
fun increment() {
_count.value = _count.value?.plus(1)
}
}
3. 在 Activity/Fragment 中绑定
kotlin
class MainActivity : AppCompatActivity() {
private val viewModel: CounterViewModel by viewModels() // 委托模式简化
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.count.observe(this) { count ->
tvCounter.text = "Count: $count"
}
btnIncrement.setOnClickListener { viewModel.increment() }
}
}
🚀 四、高级应用场景
1. 跨 Fragment 数据共享
kotlin
// 在 Activity 中获取 ViewModel
val sharedViewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
// FragmentA 和 FragmentB 使用同一实例
2. 带参数初始化(ViewModelFactory)
kotlin
class UserViewModel(userId: String) : ViewModel() { ... }
class UserViewModelFactory(private val userId: String) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return UserViewModel(userId) as T
}
}
// 使用
val factory = UserViewModelFactory("user123")
val viewModel = ViewModelProvider(this, factory).get(UserViewModel::class.java)
3. 进程死亡恢复(SavedStateHandle)
kotlin
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {
val data: LiveData<String> get() = state.getLiveData("key")
fun saveData(value: String) { state.set("key", value) }
}
⚠️ 五、最佳实践与注意事项
原则 | 正确做法 | 错误做法 |
---|---|---|
上下文引用 | 使用 AndroidViewModel 获取应用上下文 |
持有 Activity/View 引用 |
职责边界 | 仅处理 UI 数据逻辑,业务逻辑移交 Domain 层 | 在 ViewModel 中显示 Toast 或弹窗 |
数据量控制 | 存储轻量级 UI 状态,大数据用 Room/Repository | 缓存大量数据导致内存占用过高 |
异步操作 | 结合协程/LiveData 处理异步回调 | 直接在主线程执行耗时操作 |
💎 六、总结
ViewModel 是构建 健壮、可维护 Android 应用 的基石,通过:
- 解耦 UI 与数据:遵循关注点分离原则。
- 生命周期安全:自动处理配置变更与资源释放。
- 生态整合:与 LiveData、Hilt、Navigation 无缝协作。
学习建议 :结合 Jetpack Compose 实践 ViewModel 的状态提升(State Hoisting),并参考官方示例 Android Architecture Components samples 深入理解架构设计。