Android MVVM 模式详情解析
一、为什么需要 MVVM?
在早期 Android 开发中,常见架构是:
-
Activity / Fragment = 上帝类
-
UI 控制 + 业务逻辑 + 网络请求 + 数据处理 全部混在一起
典型问题:
-
❌ Activity 过于臃肿(上千行)
-
❌ 逻辑与 UI 强耦合,难以测试
-
❌ 页面复用性差
-
❌ 维护成本极高
👉 MVVM(Model--View--ViewModel) 的核心目标:
分离 UI 与业务逻辑,让界面只负责展示,逻辑由 ViewModel 处理
二、MVVM 架构概览
1️⃣ 架构组成
View(Activity / Fragment)
↓ 观察
ViewModel
↓ 调用
Model(Repository / DataSource)
| 层级 | 职责 |
|---|---|
| View | 负责 UI 展示、事件分发 |
| ViewModel | 负责业务逻辑、状态管理 |
| Model | 数据来源(网络 / 数据库 / 本地) |
三、各层职责详解
1️⃣ View(Activity / Fragment)
只做三件事:
-
初始化 UI
-
监听 ViewModel 数据变化
-
把用户操作交给 ViewModel
❌ View 不应该做的事情:
-
网络请求
-
数据解析
-
业务判断
示例:
class UserActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user)
viewModel.userLiveData.observe(this) {
// 只负责刷新 UI
textView.text = it.name
}
button.setOnClickListener {
viewModel.loadUser()
}
}
}
2️⃣ ViewModel(核心)
ViewModel 是 MVVM 的灵魂
职责:
-
处理业务逻辑
-
保存 UI 状态
-
提供可观察数据(LiveData / StateFlow)
特点:
-
不持有 View 的引用
-
生命周期比 Activity 长(配置变更不销毁)
-
可单元测试
示例:
class UserViewModel(
private val repository: UserRepository
) : ViewModel() {
private val _userLiveData = MutableLiveData<User>()
val userLiveData: LiveData<User> = _userLiveData
fun loadUser() {
viewModelScope.launch {
val user = repository.getUser()
_userLiveData.value = user
}
}
}
3️⃣ Model(数据层)
通常由 Repository 模式 组成:
Repository
├── RemoteDataSource(网络)
└── LocalDataSource(数据库 / 缓存)
Repository 的职责:
-
屏蔽数据来源
-
统一数据入口
-
控制缓存策略
示例:
class UserRepository(
private val api: UserApi
) {
suspend fun getUser(): User {
return api.getUser()
}
}
四、MVVM 中的数据驱动思想
1️⃣ 核心理念
UI = 数据的映射结果
不再主动"刷新 UI",而是:
- 数据变 → UI 自动更新
Android 常用方案:
| 技术 | 场景 |
|---|---|
| LiveData | 传统 Android |
| StateFlow | Kotlin 协程 |
| DataBinding | XML 直接绑定 |
2️⃣ LiveData vs StateFlow
| 对比项 | LiveData | StateFlow |
|---|---|---|
| 生命周期感知 | 是 | 否(需 repeatOnLifecycle) |
| Kotlin 友好 | 一般 | 非常好 |
| 冷/热流 | 热 | 热 |
| 推荐程度 | ⭐⭐⭐ | ⭐⭐⭐⭐ |
五、MVVM + Jetpack 推荐组合
官方推荐:
MVVM
+ ViewModel
+ LiveData / StateFlow
+ Room
+ Retrofit
+ Hilt
示意图:
UI → ViewModel → Repository → DataSource
↑
StateFlow
六、常见错误 & 反模式
❌ 1. ViewModel 持有 Context / View
class BadViewModel(val context: Context) // ❌
✅ 正确方式:
-
把资源、Toast、跳转交给 View
-
或使用 Event 通知
❌ 2. ViewModel 过度膨胀
把所有逻辑都塞进 ViewModel
✅ 建议:
-
复杂逻辑下沉到 UseCase / Domain 层
-
ViewModel 只做"协调者"
❌ 3. LiveData 用来做一次性事件
例如 Toast / 跳转:
LiveData<Boolean> // ❌ 会重复触发
✅ 正确方式:
-
SingleLiveEvent
-
Channel / SharedFlow
七、进阶:MVVM + Clean Architecture
View
↓
ViewModel
↓
UseCase
↓
Repository
↓
DataSource
优势:
-
更易测试
-
复杂业务可控
-
大型项目首选
八、MVVM 的优缺点总结
✅ 优点
-
清晰分层
-
UI 与逻辑解耦
-
易测试
-
生命周期安全
❌ 缺点
-
初学成本高
-
小项目略显"重"
-
设计不当仍会臃肿
九、什么时候该用 MVVM?
| 项目规模 | 是否推荐 |
|---|---|
| Demo / 小工具 | ❌ |
| 中型 App | ✅ |
| 大型 / 长期维护项目 | ⭐⭐⭐⭐ |
十、一句话总结
MVVM 的本质是:用数据驱动 UI,用 ViewModel 隔离复杂性