在现代 Android 架构中,Data 层是整个系统稳定性与可维护性的基石。无论是 Clean Architecture、MVVM、MVI,还是模块化架构,Data 层都承担着"真实世界 → 领域逻辑"的关键职责。
然而,在实际项目中,Data 层往往最容易出现隐性风险:阻塞、错误的并发模型、接口不一致、伪异步等问题会在后期演变成性能瓶颈、线程死锁、不可控的异常,甚至影响业务稳定性。
为了让 Data 层具备可维护性、可测试性与高并发安全性,我们总结出 四条绝对不能触碰的红线。这些红线不是"最佳实践",而是"底线要求"。
红线一:接口返回类型必须是 Flow 或 suspend,禁止出现其他异步形式
❌ 错误示例
- 回调 callback
- LiveData
- RxJava(除非历史包袱)
- 自定义 Listener
- Future / CompletableFuture
✔️ 正确做法
- 单次结果 → suspend fun
- 连续数据流 → Flow
为什么这是红线?
- Data 层是最底层,必须保持最小依赖与最纯粹的 Kotlin 并发模型。
- Flow + suspend 是 Kotlin 官方并发体系的核心,具备结构化并发、取消传播、背压、线程调度等能力。
- 统一接口风格能极大降低上层复杂度,让 UseCase、ViewModel、UI 层的协程模型保持一致。
额外建议
- Repository 层接口必须统一为 Flow 或 suspend,不允许混用。
- 如果是 Flow,必须明确冷流/热流语义,避免误用。
如何选择 flow 或者sunpend 请查看# Repository 方法设计:suspend 与 Flow 的决选择指南(以朋友圈为例)
红线二:禁止使用阻塞队列(BlockingQueue、LinkedBlockingQueue 等)
为什么禁止? 阻塞队列属于 Java 线程模型,与 Kotlin 协程的结构化并发完全不兼容,会导致:
- 阻塞线程池,导致 Dispatchers.IO 饱和
- 无法取消,协程取消不会中断阻塞队列
- 隐性死锁(尤其是生产者/消费者模型)
- 性能不可控,难以测试
替代方案
| 需求 | 正确方案 |
|---|---|
| 生产者/消费者 | Channel |
| 单值共享 | MutableStateFlow |
| 多值事件 | SharedFlow |
| 背压控制 | Flow + buffer() |
关键点 Data 层必须使用 协程原生并发工具,而不是 Java 并发工具。
红线三:禁止使用 Java 重锁(ReentrantLock、synchronized、wait/notify)
为什么禁止? Java 重锁属于"阻塞式锁",会导致:
- 阻塞线程 → 破坏协程调度
- 无法取消 → 协程取消不会释放锁
- 容易死锁 → 特别是在多 Repository 并发访问时
- 难以测试 → 单元测试中线程调度不可控
正确替代方案
| 场景 | 推荐工具 |
|---|---|
| 临界区保护 | Mutex |
| 原子操作 | Atomic* |
| 多协程同步 | Channel / Flow |
| 资源访问顺序控制 | Semaphore |
关键原则
Data 层必须使用 协程友好的同步原语,确保不会阻塞线程。
请参考 # 并发编程的新篇章:以Kotlin协程告别JUC的重锁与死锁风险
红线四:suspend 方法内部必须是真正的异步,禁止伪异步
❌ 错误示例


✔️ 正确示例

为什么这是红线?
- suspend 不是"异步"的代名词,它只是"可挂起"。
- 如果内部仍然阻塞线程,协程就失去意义。
- 伪异步会导致:
- IO 线程池被占满
- UI 卡顿
- 取消不生效
- 性能下降
如何判断是否是真异步?
- 是否使用了 withContext(Dispatchers.IO)?
- 是否调用了真正的异步 API(如 Retrofit suspend、Room suspend)?
- 是否避免了阻塞式 API(File、Socket、Java IO)?
总结:Data 层的四条红线不是建议,而是底线
| 红线 | 核心问题 | 正确做法 |
|---|---|---|
| 1. 接口必须是 Flow 或 suspend | 接口风格混乱、并发模型不统一 | 统一 Kotlin 并发模型 |
| 2. 禁止阻塞队列 | 阻塞线程、死锁风险 | 使用 Channel / Flow |
| 3. 禁止 Java 重锁 | 阻塞式锁破坏协程 | 使用 Mutex / atomic |
| 4. suspend 内必须是真异步 | 伪异步导致性能问题 | withContext + 真异步 API |
结语:Data 层的稳定性决定整个系统的稳定性
Data 层是所有业务的根基。
一旦底层出现阻塞、死锁、伪异步等问题,越往上层影响越大,最终会演变成难以排查的线上问题。
坚持这四条红线,就是在为整个系统的长期可维护性负责。