【发布时间】:2021-02-18 20:30:42
【问题描述】:
我读过类似的主题,但找不到正确的答案:
- How to end / close a MutableSharedFlow?
- Kotlin Flow: How to unsubscribe/stop
- StateFlow and SharedFlow. Making cold flows hot using shareIn - Android 文档
- Introduce SharedFlow - 由 Roman Elizarov 发起的 GH 讨论
在我的Repository 课程中,我有一个感冒Flow 我想分享给2 Presenters/ViewModels 所以我的选择是使用shareIn 运算符。
让我们看一下 Android 文档的示例:
val latestNews: Flow<List<ArticleHeadline>> = flow {
...
}.shareIn(
externalScope, // e.g. CoroutineScope(Dispatchers.IO)?
replay = 1,
started = SharingStarted.WhileSubscribed()
)
文档对externalScope 参数的建议:
用于共享流的 CoroutineScope。这个作用域的寿命应该比任何消费者都长,以使共享流在需要时保持活力。
但是,在寻找有关如何停止订阅 Flow 的答案时,第二个链接中投票最多的答案是:
解决方案不是取消流程,而是取消流程的启动范围。
对我来说,这些答案在SharedFlow 的案例中是矛盾的。不幸的是,我的Presenter/ViewModel 仍然收到最新数据,即使在其onCleared 被调用后。
如何预防?这是我如何在Presenter/ViewModel 中使用此Flow 的示例:
fun doSomethingUseful(): Flow<OtherModel> {
return repository.latestNews.map(OtherModel)
如果这可能有帮助,我正在使用 MVI 架构,所以 doSomethingUseful 会对用户创建的一些意图作出反应。
【问题讨论】:
-
一个 SharedFlow 是一个发布者,共享这个流的订阅者与发布者的范围是独立的。为了使其作为共享流有效,它应该比可以独立于该发布者取消而不取消它的子订阅者持续更长的时间,因为它存在于不同的范围内。文档很好地描述了这一点。我建议您设置一些简单的测试来测试行为。就 RxJava 而言,这个共享流与 ConnectableObservable 有相似之处
-
好的,我知道这些范围是相互独立的。我还指定了我的问题,添加了我的消费流用例。问题是这个
doSomethingUseful流没有明确的范围。我看到的唯一范围位于我的BasePresenter/BaseViewModel类中,该类订阅了所有意图(MVI 特定的行为)。那我应该取消吗?
标签: android kotlin kotlin-flow kotlin-coroutines