RxJava 作为事件总线被多次调用,即使只触发一次

Posted

技术标签:

【中文标题】RxJava 作为事件总线被多次调用,即使只触发一次【英文标题】:RxJava as event bus is called multiple times even when only once triggered 【发布时间】:2021-06-10 03:40:58 【问题描述】:

我正在尝试实现 RxJava 事件总线,我的用例是在订阅和发送事件时触发。但是使用我的代码,即使我发送一次事件,我也会收到多个事件。它第一次运行良好,从我第二次登录我的应用程序开始就表现得很奇怪。 IE;第一次期望的代码实现一次,第二次实现两次,依此类推。

public class RxBus 

    public RxBus() 
    

    private PublishSubject<String> bus = PublishSubject.create();

    public void send(String str) 
        bus.onNext(str);
    

    public Observable<String> toObservable() 
        return bus;
    


订阅 RxBus 的代码如下:

public void sendEvents()
        rxBus.send("Trigger event");
    

 public void startListener()
        rxBus.toObservable().subscribe(str -> 
           //do action//This is executing multiple lines
        );
    

在上面的代码中,即使当 sendEvents() 被执行一次时,包含“do action”的行也被执行了多次。那么,我在这里做错了什么。当我浏览一些博客时,他们要求在我们第二次访问该屏幕时取消订阅。但是我该如何退订呢?

非常感谢您的帮助!

【问题讨论】:

你必须记住Disposable你的subscribe返回并在startListener的上下文退出时处理它(例如,在onDestroy中)。 【参考方案1】:

简单的解决方案是声明一个字段:

SerialDisposable busDisposable = new SerialDisposable();

修改你的startListener方法:

public void startListener() 
    busDisposable.set(rxBus.toObservable().subscribe(str -> 
        // ...
    ));

这样,当您添加新订阅时,前一个订阅将被丢弃,因此您一次只能获得一个订阅。如果您的 startListener 调用不是由生命周期决定的,这很好。 (不想再接收活动时记得拨打busDisposable.dispose()。)

但是如果你在onResume/onStart/onCreate 中调用你的startListener,你最好使用Disposable 而不是SerialDisposable 并且只需在stopListener 中调用stopListener 方法onPause/onStop/onDestroy

public void stopListener() 
    busDisposable.dispose();

【讨论】:

以上是关于RxJava 作为事件总线被多次调用,即使只触发一次的主要内容,如果未能解决你的问题,请参考以下文章

RxJava 作为 Android 项目中的事件总线 - 从总线中删除事件

vue中bus.$on事件被多次绑定

vue中bus.$on事件被多次绑定

RxJava入门

Onmouseover被调用多次

解决vue使用bus被多次触发问题