Android MVI处理副作用(Side Effect)

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

先明确核心概念

在 MVI 中,副作用 指的是不改变 UI 状态但需要触发的操作(如导航、弹 Toast、网络请求、读写本地存储等),这类操作需要从 ViewModel 发送到 UI 层执行,而 MutableSharedFlowChannel 都是 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=0extraBufferCapacity=1,确保副作用一次性、不重复消费。
相关推荐
阿巴斯甜13 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker13 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952714 小时前
Andorid Google 登录接入文档
android
黄林晴16 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android