You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中RxJava2 PublishSubject转Flowable后onNext无数据发射问题

问题分析与解决方案

嘿,我一眼就看出问题出在哪了——你用的PublishSubject特性刚好和你的需求不匹配!

核心问题:PublishSubject的"健忘"特性

PublishSubject的本质是只推送订阅发生之后的事件,它不会保留任何历史事件。你在代码里的执行顺序刚好踩了这个坑:

  1. 先生成applicationList,立刻调用applicationsPublishSubject.onNext(applicationList)发射初始列表
  2. 之后才调用getApplications()完成订阅

这就导致第一次发射的初始列表,在订阅者出现之前就已经"溜走"了,订阅者自然收不到这个事件。而你用Flowable.just(applicationList)能正常工作,是因为just会创建一个直接发射指定数据的Flowable,只要一订阅就会立刻把数据推出去,和Subject的事件推送逻辑完全不同。

完美解决方案:改用BehaviorSubject

如果你既想让新订阅者一订阅就能拿到当前最新的应用列表,又能在新增应用时推送更新,BehaviorSubject就是你的最佳选择——它会自动保留最后一次发射的事件,新订阅者订阅时会先收到这个最新事件,之后的新事件也能正常接收。

修改你的代码如下:

// 初始化时直接传入初始的应用列表作为默认值
val applicationsBehaviorSubject = BehaviorSubject.createDefault(generateApplications())
val applicationsFlowable = applicationsBehaviorSubject.toFlowable(BackpressureStrategy.LATEST)

这样你就不需要手动调用onNext发射初始列表了,createDefault已经帮你做好了。之后在新增应用的方法里,只需要更新列表再发射即可(别忘了先把新应用加到列表里!):

override fun createApplication(name: String): Single<Application> {
    val application = generateApplication(name)
    applicationList.add(application)
    // 建议发射列表的不可变副本,避免外部修改原列表导致流数据不一致
    applicationsBehaviorSubject.onNext(applicationList.toList())
    return Single.just(application)
}

额外提醒

因为你用的是MutableList,如果直接发射原列表,后续对原列表的修改会影响已经推送给订阅者的数据(因为是引用传递)。所以最好像上面那样,用toList()生成一个不可变的副本再发射,保证流里的数据是固定的快照。

内容的提问来源于stack exchange,提问作者T. Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:12:01