别再 launch(IO) 了:协程线程切换的 3隐藏反模式

🧭 协程中的三大反模式:真正的问题不在 ViewModel

在 Android 项目中,协程早已成为默认选择。 但很多协程代码的问题,并不体现在"能不能跑",而是体现在职责边界是否清晰

下面这段代码,在很多项目里都能看到:

代码能工作,但从架构角度看,问题已经出现了。


反模式一:ViewModel 决定线程模型

kotlin 复制代码
viewModelScope.launch(Dispatchers.IO)

这行代码的核心问题不是"IO 用得对不对", 而是 ViewModel 不应该做这个决定

ViewModel 的职责应当是:

  • 组织业务流程
  • 暴露 UI State
  • 描述「要做什么」

而不是:

  • 决定运行在哪个线程
  • 关心 IO、CPU 等执行细节

一旦 ViewModel 指定了 Dispatchers.IO,意味着:

  • UI 层开始感知线程模型
  • Repository 被迫适配 UI 的执行策略
  • 线程语义从数据层泄漏到了展示层

这是典型的职责倒置


反模式二:UI 层手动切回 Main,是结构已经失衡的信号

这一行代码,本身就暴露了问题:

如果需要在 ViewModel 里"手动切回 Main",说明协程的启动上下文已经不合理。

结果是形成了这样的执行路径:

css 复制代码
Main → IO → Main

问题不在于多了一次线程切换, 而在于 ViewModel 正在承担"线程编排"的职责

当 UI 层开始负责调度线程时,分层就已经开始模糊。


反模式三:异常处理逻辑泄漏到 UI 层

这段代码表面上是在"兜底", 但从职责角度看,它暴露了一个更深层的问题:

UI 层正在直接感知底层异常。

这意味着:

  • ViewModel 需要知道 Repository 会抛异常
  • UI State 与异常类型产生耦合
  • 网络错误、业务错误、数据错误在 UI 层被混为一谈

异常,是实现细节; 而 UI 层只应该关心结果语义


正确的分层原则

Repository 的职责应当明确收敛为三点:

  1. 确定线程模型(IO / CPU)
  2. 捕获并转换异常
  3. 返回稳定、可消费的结果

ViewModel 的职责只有一件事:

将 Repository 的结果映射为 UI State


正确写法:线程与异常统一收敛到 Repository

Repository 层

或在需要更明确异常语义时:

线程切换和异常转换,在这里完成。


ViewModel 层

可以注意到:

  • launch 使用默认 Main
  • 没有 Dispatchers
  • 没有 withContext
  • 没有 try-catch
  • ViewModel 只消费"结果"

为什么这种结构是唯一可扩展的?

当需求发生变化时:

  • 增加缓存
  • 增加重试
  • 增加 fallback
  • 增加日志与链路追踪
  • 替换数据来源

所有改动都只发生在 Repository 层。

UI 层与 ViewModel 的代码无需调整。


总结:真正的反模式是什么?

表象 本质问题
ViewModel 切 IO 线程职责泄漏
UI 手动切 Main 协程结构失衡
UI try-catch 异常模型未收敛

结论

如果你的 ViewModel 中出现了 Dispatcherstry-catch, 那大概率不是"写法问题",而是 Repository 的职责已经失守。

协程的问题, 往往不是 API 用错了, 而是 边界被模糊了

相关推荐
一只特立独行的Yang2 小时前
Android graphics - 框架摘要
android
AC赳赳老秦4 小时前
DeepSeek优化多智能体指令:避免协同冲突,提升自动化流程稳定性
android·大数据·运维·人工智能·自然语言处理·自动化·deepseek
峥嵘life7 小时前
Android16 【CTS】CtsWindowManagerDeviceAnimations存在fail项
android·linux·学习
阿拉斯攀登8 小时前
第 7 篇 安卓驱动开发的灵魂:字符设备驱动框架,从原理到最简实战
android·驱动开发·rk3568·嵌入式驱动·安卓驱动
阿拉斯攀登9 小时前
第 1 篇 入坑不亏!瑞芯微 RK 平台 + 安卓驱动开发,小白全维度扫盲
android·驱动开发·rk3568·嵌入式驱动
Android系统攻城狮9 小时前
Android tinyalsa深度解析之pcm_params_get调用流程与实战(一百六十二)
android·pcm·tinyalsa·android hal·audio hal
zh路西法9 小时前
【C语言简明教程提纲】(四):结构体与文件定义和操作
android·c语言·redis
常利兵9 小时前
Jetpack Compose 1.8 新特性来袭,打造丝滑开发体验
android
牢七10 小时前
百家cms 审计 未完成
android·ide·android studio
hjxu201610 小时前
【 MySQL 速记5】插入
android·数据库·mysql