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,确保副作用一次性、不重复消费。
相关推荐
非凡ghost3 小时前
JRiver Media Center(媒体管理软件)
android·学习·智能手机·媒体·软件需求
席卷全城3 小时前
Android 推箱子实现(引流文章)
android
齊家治國平天下3 小时前
Android 14 系统中 Tombstone 深度分析与解决指南
android·crash·系统服务·tombstone·android 14
maycho1235 小时前
MATLAB环境下基于双向长短时记忆网络的时间序列预测探索
android
思成不止于此6 小时前
【MySQL 零基础入门】MySQL 函数精讲(二):日期函数与流程控制函数篇
android·数据库·笔记·sql·学习·mysql
brave_zhao6 小时前
达梦数据库(DM8)支持全文索引功能,但并不直接兼容 MySQL 的 FULLTEXT 索引语法
android·adb
sheji34166 小时前
【开题答辩全过程】以 基于Android的网上订餐系统为例,包含答辩的问题和答案
android
easyboot6 小时前
C#使用SqlSugar操作mysql数据库
android·sqlsugar
为码消得人憔悴7 小时前
Android perfetto - Perfetto 新手入门指南
android·性能优化