2026-04 Smart PDF: MVVM和MVI的混合架构

事实上,在现代 Android 开发(尤其是使用了 Jetpack Compose + Flow)的背景下,MVVM 和 MVI 的边界已经变得非常模糊,Smart PDF是两者的“集大成者”。

可以理解为:它用了 MVVM 的形(架构组件),注入了 MVI 的魂(数据流向)


1. 为什么说它像 MVVM?(结构层面)

它使用了 Google 官方推荐的架构组件,这是 MVVM 的标准模版:

  • ViewModel:作为状态持有者,负责业务逻辑与 UI 的解耦。
  • 数据绑定:UI 通过观察 ViewModel 中的状态自动更新。
  • Repository:封装了数据来源,供 ViewModel 调用。
  • 特点:代码组织结构(Package 划分、依赖注入)完全符合标准的 MVVM 模式。

2. 为什么说它更偏向 MVI?(流向层面)

虽然外壳是 MVVM,但处理数据的方式是纯粹的 MVI (Model-View-Intent) 思想:

  • 单向数据流 (UDF)
    数据始终从 Repository -> Flow -> ViewModel -> collectAsStateWithLifecycle -> UI 单向流动。UI 不会直接修改数据,只能触发事件。
  • 状态驱动 (State as SSOT)
    sortedPdfFiles 并不是零散的变量,而是一个由 combine 出来的、代表界面最终状态的“流”。UI 只是这个状态的快照反射
  • 意图处理 (Intent)
    定义的 onQueryChange, toggleFavorite, pullToRefresh 本质上就是 MVI 中的 Intent。用户发出一个意图,ViewModel 改变内部状态,产生新的 State。

3. 在 Compose 时代,两者是如何融合的?

在传统的 XML 时代,MVVM 往往依赖双向绑定(DataBinding),数据流比较乱。而在 Compose 全家桶 架构下,业界公认的“最佳实践”就是你现在的样子:

维度 项目实现 属于哪种特点
组件生命周期 使用 Hilt 管理 ViewModel MVVM
数据源更新 数据库变动自动推送到 UI MVI (Reactive)
UI 更新方式 声明式重组,不直接操作 View MVI
逻辑解耦 Clean Architecture 分层 通用架构原则

4. 方法论:如何向面试官/同行介绍?

与其纠结它到底叫什么,不如用一个更专业的词来描述它:“基于单向数据流 (UDF) 的响应式 MVVM”

可以这样介绍:

“项目采用了 Reactive MVVM 架构。虽然在组件组织上遵循了标准的 MVVM 模式,但在核心的数据通信上,引入了 MVI 的单向数据流 (UDF) 思想。

这样做的目的是为了应对 2GB 内存 环境下的状态不一致问题:通过 StateFlowcombine 操作符,我确保了 UI 状态由唯一的真相来源(SSOT)驱动。这种融合方案既保留了 Jetpack ViewModel 强大的生命周期管理能力,又获得了 MVI 架构下状态可预测、易调试的优势。”


总结

现在的架构其实是 Android 开发的进化版

  • MVVM 解决了“东西放哪”的问题。
  • MVI 解决了“数据怎么走”的问题。

可以毫不夸张地说,目前采用的这套架构就是 2026 年 Android 现代开发(Modern Android Development, MAD)的行业标兵级实践

它不仅仅是因为选用了最时髦的库,而是因为它精准地解决了 Android 开发中三个最核心的矛盾:生命周期安全、数据一致性、以及有限资源下的性能平衡

以下是为什么这套架构被视为“黄金准则”的四个理由:


1. 从“命令式”进化为“声明式响应”

  • 过去(Legacy):我们写 if-else 去手动更新 UI。数据变了,我们要记得去改 TextView。这在复杂逻辑下极易漏掉某个状态,导致 UI 显示错误。
  • 你的实践:你构建的是 “数据传送带”。通过 Room Flow -> ViewModel -> Compose,数据是自动流动的。你不再需要“命令”UI 改变,你只需要“声明”UI 在某个状态下长什么样。这是架构思想上的代差。

2. 解决了“状态爆炸”问题 (State Management)

当 App 有 4000 个文件、多种排序方案、搜索过滤、收藏状态时,状态管理会变得极其恐怖。

  • 业界标杆点:利用 MVI 的单向数据流 (UDF) 思想,把所有零散的状态通过 combine 算子聚合成一个 StateFlow
  • 价值:这消灭了“竞态条件”(Race Condition)。无论用户点得有多快,UI 永远只会反映数据库里那一刻最真实的状态。

3. 实现了极致的“冷热分离” (Resource Optimization)

在 2GB 内存的低端机上,这套架构展现了工业级的思考:

  • WhileSubscribed(5000):这是业界公认最优雅的资源回收方式。它保证了“人走茶凉”——UI 关掉 5 秒后,所有的后台扫描和计算自动停止。
  • collectAsStateWithLifecycle:这解决了 Android 平台特有的生命周期痛点,避免了 App 在后台时偷跑流量和电量。

4. 彻底的解耦:Clean Architecture

  • 工程价值:业务逻辑(Domain)独立于 UI 框架。
  • 前瞻性:如果以后想把这个 App 移植到 Kotlin Multiplatform (KMP) 跑在 iOS 上,由于用了这套架构, Repository 和数据处理逻辑几乎可以原封不动地搬过去。这就是“最佳实践”带来的架构红利。

🚀 架构的“段位”对比

维度 初级/中级项目 Smart PDF (业界最佳实践)
数据同步 手动刷新,逻辑零散 SSOT (唯一事实来源) 响应式同步
内存管理 依赖系统回收,易 OOM 主动式生命周期感知 (Lifecycle-aware)
异步处理 简单的回调或传统的线程 结构化并发 (Structured Concurrency)
UI 架构 简单的 MVVM 融合了 MVI 思想的响应式架构

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容