收到多个事件 - Greenrobot事件总线

9
我在我的应用程序中使用了Greenrobot的EventBus,它运行良好。
然而,如果我按下返回按钮关闭应用程序,然后立即重新启动应用程序,似乎我会收到两次事件。如果我再这样做一次,我就会收到三次,以此类推。
我正在检查日志并进行调试,看看是否有多个类的实例,或者是否注册了多次,但我看不到任何额外的类,并且使用isRegistered返回false。
有什么想法吗?
谢谢

你能发一下你的代码吗? - Orhan Obut
1
我同意crazymaik的说法--感觉好像你漏掉了某个unregister()调用。请记住,返回按钮并不会“关闭应用程序”,因为你的进程仍然存在,至少还要一段时间。返回按钮只会销毁前台活动。 - CommonsWare
5个回答

16

你的register/unregister调用是否正确配对?例如,如果在Activity.onResume()register(),那么在Activity.onPause()中是否调用了unregister()

关闭所有活动并不会终止您的进程。也就是说,所有已注册的类仍然存在,您必须明确地清理和取消注册事件总线,或者在Activity回来时重新使用它们。


我认为你是对的,我已经使用grep命令查看了一下,我的寄存器数量超过了未注册的数量。然而,我不确定我是否使用得正确。现在我明白我应该在最初的问题中添加更多信息。我正在尝试使用LibGDX编写游戏,它几乎完全是用Java编写的。在这方面,我没有像使用Activities/Fragments那样使用它,也许我误用了eventbus。我在普通的Java类中使用它。我在构造函数中进行注册,但我不知道在哪里取消注册。我不知道有没有一个方法会在类的GC时被调用? - Russ Wheeler
我刚刚在我没有注销的类中添加了一个对isRegistered的调用,并且我收到了false,这意味着它仍未注册吗?或者这是错误的,现在堆上有两个类,旧的仍然注册,以及这个新的? - Russ Wheeler
我想我已经解决了。我在所有使用EventBus的类中添加了一个名为unRegister()的方法,这些类不是活动或没有LibGDX dispose()方法。然后我必须仔细确保在游戏关闭时取消注册所有内容。看起来它正在工作,但如果有问题我会再回来找你们的。谢谢大家。 - Russ Wheeler

4

这是比较老的问题,但如果有人也遇到了这个问题,请小心使用EventBus在像Fragments或其他类一样的动态生成的组件中; 我当时并不理解为什么它们会向EventBus发布多次,但我认为这可能与此有关(我有超过一个动态生成的Fragment)。一旦我将register(), unregister(), onEvent()放入父Activity代码中(它还很方便地使用了onPause()onResume()),就可以正常工作了。


2

当我使用以下代码发送事件时:

EventBus.getDefault().postSticky(new Event("Hii !"));

在我的情况下发生了相同的事情。
当我回到该活动时,事件会被多次接收。
因此,在onEvent方法中接收后,我通过删除事件来解决了这个问题。
这解决了我的问题。
使用:removeStickyEvent(object)

原始答案:Original Answer

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
    public void onEvent(Event event) {
        /* Do something */
        EventBus.getDefault().removeStickyEvent(event);
}

1
问题不在于事件实际上被触发了多次,而在于处理程序被调用了多次。如上面的代码所示,每次创建对象时都会调用bus.register方法;由于活动生命周期的影响,这种情况发生了多次,导致处理程序被多次调用。

0

我有一个特定的案例想要分享,也许可以帮助其他人。 在我们的项目中,我们使用一个父活动作为所有活动的父类,我们在父类中为每个活动注册和注销EvenBus。 在我们的某个活动中,在调用先前活动的EventBus之前,我们调用了EventBas。然后我们就会触发两次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接