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,确保副作用一次性、不重复消费。
相关推荐
执明wa12 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio
404_coder12 小时前
源码视角下的 Android 开机流程:从 Zygote、SystemServer 到 Launcher
android
二流小码农12 小时前
鸿蒙开发:以登录案例了解代码架构MVVM
android·ios·harmonyos
用户693717500138413 小时前
从代码生产者到 AI 协作者:软件工程师的角色重构
android·前端·后端
GitLqr13 小时前
别在 Flutter 的 main() 里乱锁屏幕方向,小心 iPad 分屏功能被你搞没了
android·flutter·ios
sg_knight14 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db
爱笑鱼14 小时前
Binder(四):ioctl(BINDER_WRITE_READ) 之后,事务怎样到达目标进程?
android
AFinalStone14 小时前
Android 7系统休眠唤醒(二)开机全链路—BootROM到Launcher
android·电源管理·休眠唤醒
Mr YiRan14 小时前
Android NDK开发之统计到未被回收的图片
android