Android Otto(事件总线),将事件片段发送到片段,但不接收

Android Otto(事件总线),将事件片段发送到片段,但不接收,android,otto,Android,Otto,MainActivity有一个NavigationDrawer,每个导航菜单都会带来片段而不是新活动 有一个设置片段,若我更改了导航菜单的顺序,它应该立即反映到NavigationDrawerFragment 我在SettingsFragment中发布事件,但它并没有出现在NavigationDrawerFragment上 我做了一辆安德洛巴士 public class AndroidBus extends Bus { private final Handler mainThread

MainActivity有一个NavigationDrawer,每个导航菜单都会带来片段而不是新活动

有一个设置片段,若我更改了导航菜单的顺序,它应该立即反映到NavigationDrawerFragment

我在SettingsFragment中发布事件,但它并没有出现在NavigationDrawerFragment上

我做了一辆安德洛巴士

public class AndroidBus extends Bus {

    private final Handler mainThread = new Handler(Looper.getMainLooper());

    public AndroidBus() {
        super(ThreadEnforcer.ANY);
    }

    @Override
    public void post(final Object event) {
        if (BuildConfig.DEBUG) Ln.d("BUS: SYNC current thread="+Thread.currentThread().getName()+", post=" + event + " bus=" + this);
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            mainThread.post(new Runnable() {
                @Override
                public void run() {
                    post(event);
                }
            });
        }
    }

    @Override
    public void register(Object object) {
        super.register(object);
        if (BuildConfig.DEBUG) Ln.d("BUS: SYNC current thread="+Thread.currentThread().getName()+", register=" + object + " bus=" + this);
    }

    @Override
    public void unregister(Object object) {
        super.unregister(object);
        if (BuildConfig.DEBUG) Ln.d("BUS: SYNC current thread="+Thread.currentThread().getName()+", unregister=" + object + " bus=" + this);
    }
}
我用匕首将总线对象注入每个碎片 我在onActivityCreated中注册该片段,并在OnStroyView中注销它

如果我发布事件,它不会被传递,我会看到DeadEvent日志

08-07 11:00:27.203    3519-3519/com.test.app.debug D//AndroidBus.java:40﹕ main BUS: SYNC current thread=main, register=com.test.app.ui.MainActivity@536fa3b0 bus=[Bus "default"]

08-07 11:00:27.231    3519-3519/com.test.app.debug D//AndroidBus.java:40﹕ main BUS: SYNC current thread=main, register=NavigationDrawerFragment{536b79a4 #0 id=0x7f0a0072} bus=[Bus "default"]

08-07 11:00:27.247    3519-3519/com.test.app.debug D//MainActivity.java:127﹕ main SYNC: register: bus=[Bus "default"]
08-07 11:00:27.251    3519-3519/com.test.app.debug D//AndroidBus.java:40﹕ main BUS: SYNC current thread=main, register=SettingsFragment{536b7a2c #1 id=0x7f0a0071} bus=[Bus "default"]


08-07 11:00:31.415    3519-3519/com.test.app.debug D//AndroidBus.java:24﹕ main BUS: SYNC current thread=main, post=com.test.app.events.SettingsUpdatedEvent@536d1aa4 bus=[Bus "default"]
08-07 11:00:31.415    3519-3519/com.test.app.debug D//AndroidBus.java:24﹕ main BUS: SYNC current thread=main, post=com.squareup.otto.DeadEvent@5352027c bus=[Bus "default"]
我也在onCreate方法中注册MainActivity,如果我在MainActivity中订阅相同的事件,它将接收该事件


感谢您阅读本文,我希望有人能给我一些启发。

好的,您的第二个片段没有收到事件消息,因为它创建得太晚了,而第一个片段在调用第二个片段的
onActivityCreated
之前发布事件
要解决此问题,应将事件对象保留在内存中,直到创建第二个片段并可以接收此事件。我不确定
Otto-Bus
是否支持此功能。第二个选项是将事件对象保留在activity类中,第二个片段通过调用
getActivity()
获取它,但这种方式会破坏
EventBus
的含义。
所以我推荐最后一个:使用,它支持比Otto更多的特性,例如:在主线程和后台线程上发布,缓存事件(粘性事件)。您的问题将通过将粘性事件与
GreenRobot EventBus
一起使用来解决:

   // Register stictky subscribers on onResume()
   EventBus.getDefault().registerSticky(this);

   // Unregister subscriber on onPause()
   EventBus.getDefault().unregister(this);

   // your subscribe event here 
   public void onEvent(AnyEventType event) {

   }

   // or subscribe event on main thread 
   public void onEventMainThread(AnyEventType event) {

   }

   // Post sticky events from the first fragment to the bus:
   EventBus.getDefault().postSticky(AnyEventType);

更新:可能我对您的问题的看法是错误的,是同一个问题,并且已通过删除
ThreadEnforcer解决。任何
,您都可以尝试。

我重新审视了这个问题,发现了我的愚蠢。原因是我使用了不同的
@Subscribe
注释。当您同时使用
Otto
Guava
库时,可能会发生这种情况。因此,在Android应用程序中同时使用两个库时,请注意这一点

-import com.google.common.eventbus.Subscribe;
+import com.squareup.otto.Subscribe;

我还想在对话中补充一点,您不能在
接口
超类
中声明
@Subscribe
方法,它们将不会被调用

Otto
文档:

注册只会在立即类类型上找到方法。与Guava事件总线不同,Otto不会遍历类层次结构,也不会从带注释的基类或接口添加方法。这是一个明确的设计决策,旨在提高库的性能,并保持代码简单明了

greenrobot提供的事件总线支持此功能:

谢谢您的回答,不过,首先,这两个片段都是在发布事件之前创建的。第二次我在主线程中发布事件,我发布的日志是confirm tware。因此,更改ThreadEnforcer.ANY没有任何帮助。如果我尝试GreenRobot EventBus,并解决了这个问题,我将转向它。谢谢你的建议。
GreenRobot的EventBus
解决了这个问题,我认为它应该发生在
Otto
中。但是我真的不知道为什么这对奥托不起作用。我甚至不需要GreenRobot的EventBus中的sticky事件来执行此操作。我只是使用了与
Otto
相同的代码,在
Otto
的注册代码中使用了相同的注册代码,在
Otto
的注册代码中使用了相同的发布代码,在你的post方法中我发现了一个奇怪的问题:为什么在这个问题上使用递归:
post(Event)?根据这个答案,您的方法可能是错误的,或者您可以使用
AndroidBus.super.post(event)谢谢,我把它改为使用super.post,但是它仍然不起作用。我将使用GreenRebot的EventBus。