Android MVI处理副作用(Side Effect)

Android MVI 架构中处理副作用(Side Effect) 时,该选择 MutableSharedFlow 还是 Channel,并了解它们的适用场景和核心差异?

先明确核心概念

在 MVI 中,副作用 指的是不改变 UI 状态但需要触发的操作(如导航、弹 Toast、网络请求、读写本地存储等),这类操作需要从 ViewModel 发送到 UI 层执行,而 MutableSharedFlow 和 Channel 都是 Kotlin 协程中用于跨协程通信的工具,但设计初衷和语义完全不同。

核心差异与 MVI 场景适配

1. MutableSharedFlow(推荐:绝大多数 MVI 副作用场景)

MutableSharedFlow 是热流(Hot Flow),核心特点是:

  • 支持多订阅者接收数据(即使 UI 重建,重新订阅也可灵活控制是否接收历史数据);
  • 可配置缓冲、重放策略(replay)和背压策略,适配 MVI 副作用 "一次性、不重复消费" 的特点;
  • 与 Flow 生态深度兼容(可使用 map/filter 等操作符处理副作用);
  • 官方已将 BroadcastChannel(多订阅者 Channel)标记为废弃,推荐用 SharedFlow 替代。

MVI 中推荐配置:

  • replay = 0:不重放历史副作用(副作用是一次性指令,页面重建后无需重复执行);
  • extraBufferCapacity = 1:缓冲 1 个副作用(避免高频发送时丢失);
  • onBufferOverflow = BufferOverflow.DROP_OLDEST:缓冲满时丢弃最旧的副作用(优先处理最新指令)。

2. Channel(仅适用于特定场景)

Channel 是冷流(Cold Stream),核心特点是:

  • 默认一对一通信(一个发送者对应一个接收者),确保每个副作用仅被消费一次;
  • send() 方法是挂起函数(缓冲满时会阻塞,直到接收方处理);
  • 语义更偏向 "任务队列",适合需要严格串行处理、消费确认的场景。

MVI 中适用场景:

  • 副作用是耗时任务,且需要严格按顺序执行(如有序的数据库写入操作);
  • 必须确保每个副作用都被处理,不允许丢失(如支付相关的关键指令)。

总结

  1. 绝大多数 MVI 副作用场景选 MutableSharedFlow:它是官方推荐方案,适配副作用 "一次性 UI 指令" 的特点,与 Flow 生态兼容更好,配置灵活且非阻塞发送。
  2. 仅特定场景用 Channel :需要严格串行处理、消费确认,或关键任务不允许丢失时才考虑,注意 send() 是挂起函数,需处理阻塞风险。
  3. 核心配置建议 :SharedFlow 建议设置 replay=0、extraBufferCapacity=1,确保副作用一次性、不重复消费。
相关推荐
jack186894 小时前
安卓手机忘记锁屏密码怎么办? 无需密码也可解锁
android·智能手机
应用市场7 小时前
不用一张图片的像素小游戏:小人是字符串,房间是矩形,平衡靠两千个假玩家
android·kotlin·游戏开发
stevenzqzq8 小时前
android 对渠道的理解
android
QEasycloud8 小时前
BOM接口抛转失败钉钉通知策略实战教程:MySQL异常日志到钉钉消息的端到端配置
android·mysql·钉钉
AIsoft_86898 小时前
医患交流内容如何做好记录?
android·iphone
蒸鱼Yuzheng9 小时前
Android Native 崩溃证据链:Tombstone、Build ID 与 Trace 如何联合归因
android·ndk·tombstone·调试符号·崩溃分析
事圆则缓9 小时前
Kotlin 变量与函数:把页面状态和行为写成清楚的契约
android·开发语言·kotlin
hunterandroid9 小时前
MVVM 迁移到 MVI:复杂页面状态如何收敛
android
妖星9 小时前
Android 开机动画定制:从 bootanimation.zip 到源码编译
android
临期冰淇淋10 小时前
MTK平台 安卓16 GMS报错修改
android·java·前端