MVI架构核心设计思想及实际项目应用总结
一、MVI架构的核心设计思想
MVI(Model-View-Intent)架构的核心设计思想并非单纯的组件分层规范,而是围绕数据流构建界面更新逻辑的三大核心原则 (响应式编程、单向数据流、唯一可信数据源),本质是用数据流思维统一管理界面的所有状态变化,让复杂交互下的界面更新可预测、可追溯、可维护,其核心思想拆解如下:
1. 唯一可信数据源:界面状态的"单一事实来源"
这是MVI的基础,解决了传统架构中多状态源不一致、更新逻辑散落的核心痛点。
- 核心要求:将同一业务/整个界面 的所有状态(包括控件样式、加载状态、交互结果、异常提示等)聚合为一个/若干个独立的State数据类 ,成为界面刷新的唯一数据来源,界面所有展示逻辑仅依赖该State,不再分散依赖多个数据/回调。
- 可信保障:通过写时拷贝(COW) + 状态字段只读(
val)限制,解决多线程并发读写的线程安全问题;禁止直接修改状态,必须通过拷贝生成新状态,保证状态的不可变性和一致性,避免状态篡改导致的界面异常。 - 灵活落地:复杂界面无需强行单-State到底,可按相互独立的业务模块拆分多个State(控件A变化不影响控件B),既保证"唯一",又避免出现"上帝类"。
2. 单向数据流:界面交互的"单向流转规则"
这是MVI的核心流转方式,是唯一可信数据源 的必然结果,让整个界面的状态变化形成闭环且方向唯一的链路。
核心链路:View → Intent → 状态处理器(ViewModel/Presenter) → State → View
- View(界面)将用户操作(点击、刷新、输入等)抽象为Intent(意图) (本质是事件数据),发送给状态处理器;
- 状态处理器接收Intent,结合业务逻辑处理后,生成新的State(界面状态) ;
- View观察State的变化,根据新State刷新界面,完成一次交互闭环。
核心要求:数据只能单向流动,不允许反向传递(如View不能直接修改State,State处理器不能直接操作View),所有界面变化都必须通过这条链路触发,让每一次状态变更都有迹可循。
延伸扩展:可将数据流链路延伸至网络、数据库层(Repository → 状态处理器),形成更大的单向闭环,保证整个APP的数据流一致性。
3. 响应式编程:数据流的"动态处理范式"
这是MVI的技术落地手段 ,让单向数据流从"设计规则"变成可实现的代码逻辑,解决了命令式编程中事件处理分散、变化传播被动的问题。
- 核心要求:将Intent(事件流) 和State(状态流) 都以响应式流 (如Kotlin Flow/StateFlow/SharedFlow)的形式存在,全程采用声明式的方式处理数据流。
- 核心特性:利用响应式编程的变化自动传播、数据流变换、背压处理 能力,实现Intent的统一收集、业务逻辑的流式处理、State的实时推送;借助流的操作符(
map/filter/combine/节流/防抖等),可轻松实现复杂的事件处理逻辑。 - 与命令式的区别:命令式是"手动调用方法触发更新",分散且不可控;响应式是"定义数据流变换规则,变化自动传播",所有事件/状态都在流中流转,实现统一控制、自动响应。
4. 额外核心设计:状态与事件的严格区分(究极体优化)
这是MVI对数据流的精细化打磨 ,解决了传统架构中持久化状态与一次性事件混淆导致的粘性问题(如重复弹窗、重复跳转),是核心思想的重要补充:
- State(状态) :持久化、可恢复、连续的界面状态(如按钮样式、列表数据、加载状态),用可粘性的流(StateFlow)存储,允许新订阅者接收历史状态(如页面重建后恢复界面);
- Event(事件) :一次性、消费即毁、离散的 操作通知(如弹窗、吐司、页面跳转),用非粘性的流(SharedFlow,
replay=0)或事件包装类存储,保证每个事件仅被消费一次。
核心思想的底层逻辑:用数据流理解所有界面变化
MVI的所有设计思想都围绕一个核心底层逻辑:将界面的所有交互和变化都抽象为数据流。
- View不再是被动的"被更新者",而是数据流的生产者 (发送Intent)和消费者(接收State/Event);
- 状态处理器(ViewModel/Presenter)是数据流的处理中心,负责将Intent流转换为State/Event流;
- 整个界面的更新过程,本质是数据流的生产、处理、传播、消费的过程。
与MVP/MVVM的核心差异:重"流"而非重"组件"
MVI并非MVP/MVVM的替代方案,而是一套可基于MVP/MVVM落地的数据流设计原则:
- MVP/MVVM的核心是指定组件角色(Presenter/ViewModel作为状态持有者),但对Model的定义模糊,易导致使用不当;
- MVI不限制具体的组件角色(可复用ViewModel/Presenter),核心关注界面更新的整个数据链路的流动方式和方向,只要遵循三大核心原则,无论用何种组件,都可实现MVI的效果。
总结
MVI架构的核心设计思想可概括为:以「唯一可信数据源」为基础,以「单向数据流」为流转规则,以「响应式编程」为技术手段,将界面的所有交互和状态变化都抽象为可预测、可追溯的数据流 ,最终解决复杂Android界面开发中状态不一致、bug难排查、更新逻辑散落、维护成本高的核心痛点。
二、MVI在实际项目中的应用(混合架构模式)
实际项目里几乎全是"混搭"模式,没有哪个正经项目是纯纯的一种架构到底。核心认知是:MVP / MVVM 是分层结构,MVI 是数据流风格,两者完全可以共存。
一、现实里最常见的真实架构
绝大多数 Android 项目,现在都是这种混合体:
-
整体分层:MVVM 结构
- View:Activity / Fragment / Compose
- ViewModel:业务逻辑、状态管理
- Model:Repository、DataSource、网络数据库
-
内部数据流:MVI 思想
- 唯一 State
- 单向数据流
- Intent / Event 事件驱动
也就是:外壳是 MVVM,内核是 MVI
二、为什么一定会混用?
-
MVVM 解决"职责分层" 这些是 MVI 本身不负责的。
- 生命周期管理
- 页面与逻辑解耦
- 数据持久化(ViewModel 存活特性)
-
MVI 解决"状态混乱" 这些是原生 MVVM 没管好的。
- 多状态并发不一致
- 弹窗、跳转、Toast 乱飞
- 复杂交互页面逻辑不可追溯
所以项目里自然会:用 MVVM 搭架子,用 MVI 管状态。
三、常见混搭姿势
- 简单页面:纯 MVVM列表、详情页,逻辑简单,没必要上全套 MVI。
- 复杂交互页面:MVVM + MVI 强化直播间、表单、聊天页、复杂筛选页,上 State + Intent + Reducer。
- 老模块重构:MVP 里偷偷加 MVI 数据流不推翻原有结构,只把状态收拢成唯一 State,事件统一分发。
- 跨页面/全局状态:MVI 风格全局状态机登录态、主题、全局配置,用单例 + StateFlow 做唯一可信源。
四、一句话总结真实场景
- 架构从来不是非此即彼
- MVVM 是结构,MVI 是风格
- 项目里普遍是:外层 MVVM,复杂页面 MVI 化,简单页面随便写