ViewModel 简介
什么是 ViewModel?
说白了,ViewModel 就是帮你管数据的。屏幕一转、App 被回收,数据不会丢。
我刚学 Android 的时候,总把数据放在 Activity 或 Fragment 里。结果呢?一旋转屏幕,Activity 重建,输入框的内容全没了。用户骂我,老板也骂我。后来才知道,Google 早就给了解决方案——ViewModel。
ViewModel 是 Android Jetpack 的一部分。它专门用来存储和管理 UI 相关的数据。它的设计思想很简单:数据与界面解耦。Activity 可以死,但 ViewModel 活着,数据也就活着。
- 自动保留数据,屏幕旋转不丢
- 生命周期意识,自动清理
- 跨 Fragment 共享数据
为什么需要 ViewModel?
这个问题我问过自己很多遍。你看啊,一个 App 里最怕的就是「状态混乱」。Activity 重建、Fragment 切换、网络请求回调还没回来……这些场景下,数据很容易丢失或重复加载。
用过 onSaveInstanceState 吗?那玩意儿只适合存少量序列化数据。图片、列表、复杂对象,根本塞不进去。ViewModel 就不一样,它直接存在内存里,只要你进程没被杀,数据就在。
我个人习惯把 ViewModel 当作「数据管家」。UI 只负责展示和通知,ViewModel 负责处理逻辑和缓存。这样写出来的代码,测试也好测,维护也轻松。
ViewModel 的生命周期
ViewModel 的生命周期和 Activity/Fragment 不同。它的范围是从 Activity/Fragment 创建开始,到它真正被销毁为止。
看图就明白了:
图的左边是 Activity 的常规生命周期,右边是对应的 ViewModel 状态。关键点:Activity 旋转时 ViewModel 不会销毁。只有 Activity 真正 finish(比如用户按返回键),ViewModel 才会执行 onCleared()。
生命周期的陷阱
我曾经在项目里遇到一个问题:在 ViewModel 中持有 Activity 的 Context。结果旋转屏幕时,旧 Activity 无法被回收,导致内存泄漏。排查了好久才发现是 ViewModel 里传了 Activity 实例。正确的做法是用 Application 的 Context,或者直接使用 AndroidViewModel。
AndroidViewModel(application: Application)。
ViewModel 的使用方式
用起来很简单,几句话就搞定:
// 创建一个 ViewModel
class MyViewModel : ViewModel() {
val userData = MutableLiveData<User>()
fun loadUser(userId: String) {
// 加载数据的逻辑
}
}
// 在 Activity 或 Fragment 中使用
val viewModel: MyViewModel by viewModels()
viewModel.userData.observe(this) { user ->
// 更新 UI
}
| 方法 | 说明 |
|---|---|
viewModels() |
在 Activity 中获取当前 Activity 范围的 ViewModel |
activityViewModels() |
在 Fragment 中获取共享的 Activity 范围 ViewModel |
ViewModelProvider |
自定义工厂模式创建 ViewModel(适用于带参数的情况) |
我个人更推荐 by viewModels() 委托写法,省去样板代码。如果你需要传入 Application 或自定义参数,可以用 ViewModelProvider.Factory。
activityViewModels()。这样两个 Fragment 都能访问同一个 ViewModel,实现通信。我曾经用它做购物车页面,体验很好。
小结
ViewModel 不是个复杂的东西。它的核心就是「延长数据的生存期」。你只管写业务逻辑,ViewModel 帮你扛住配置变更和进程重建。
记住三个点:
- 不要直接持有 Activity 引用
- 用 LiveData 或 StateFlow 暴露数据
- 生命周期绑定,自动清理
嗯,这就是 ViewModel 的基本面貌。后面会和 DataStore 配合,你会看到它真正的威力。