【大前端】【Android】一文详解Android MVVM 模式详情解析

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)

只做三件事:

  1. 初始化 UI

  2. 监听 ViewModel 数据变化

  3. 把用户操作交给 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 隔离复杂性


相关推荐
用户938515635078 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
CodeSheep9 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
鱼樱前端9 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
浮生望9 小时前
React + TypeScript 组件设计进阶:从类型约束到无状态组件的三次进化
前端
90后的晨仔10 小时前
Mac 开发 uni-app 终极方案:让安卓模拟器彻底脱离 Android Studio 独立运行
前端·vue.js
90后的晨仔10 小时前
别再搞混了!uni-app 中 node_modules 和 uni_modules 到底是什么关系?
前端
kyriewen11 小时前
面试官问"这段逻辑为什么这样写"——我才发现,这半年我写的代码,我自己都解释不了
前端·javascript·面试
YB137511 小时前
jetpack compose 副作用 SideEffect
android·kotlin
谢小飞11 小时前
大文件上传很难?学会这招,GB文件秒传不是梦
前端·node.js
程序员黑豆11 小时前
Windows 系统 Java 环境变量配置全攻略:解决“不是内部或外部命令”
java·前端·ai编程