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,确保副作用一次性、不重复消费。
相关推荐
恋猫de小郭7 分钟前
Flutter 可以更直接地调用原生 API 了,Dart Direct Native Interop
android·前端·flutter
2501_9160088923 分钟前
iPhone 设备信息查看,用 KeyMob 看型号、序列号、电池健康和 UDID
android·ios·小程序·https·uni-app·iphone·webview
好的佩奇11 小时前
蓝牙之通信架构
android·flutter·蓝牙
FlightYe11 小时前
视界原理之3D视频(四):裸眼、眼镜和头显
android·linux·c++·3d·ffmpeg·音视频
诸神黄昏EX12 小时前
Android fw BatteryService
android
alexhilton12 小时前
提升 Android Compose 页面的流畅度
android·kotlin·android jetpack
撩得Android一次心动13 小时前
Android中Gradle网络下载超时、更改存放位置(解决方案)
android·gradle
HQL_seven15 小时前
【Activity】Android Activity详解
android
AI2中文网15 小时前
安卓 15/16 手机软键盘遮挡输入框、布局顶不上去?已解决:重新编译即可
android·智能手机
字节暗面15 小时前
Android APP 加固横评记录:爱加密、梆梆、网易易盾与腾讯 ACE
android·逆向工程·加固