4

MainActivity 有一个 NavigationDrawer,每个导航菜单都会带来 Fragment 而不是新的 Activity。

有设置片段,如果我更改导航菜单的顺序,它应该立即反映到 NavigationDrawerFragment。

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

我做了一个 AndroidBus extends Bus

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);
    }
}

我通过 Dagger 将总线对象注入每个片段,并在 onActivityCreated 中注册片段,并在 DestroyView 中取消注册。

如果我发布事件,它不会被传递,我会看到 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 订阅相同的事件,它会接收到该事件。

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

4

3 回答 3

12

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

-import com.google.common.eventbus.Subscribe;
+import com.squareup.otto.Subscribe;
于 2014-09-01T01:26:21.037 回答
2

我还想补充一点,你不能在or中声明@Subscribe方法,它们不会被调用。interfacesuper class

Otto文档:

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

EventBus由 greenrobot 支持此功能: https ://github.com/greenrobot/EventBus

于 2016-08-23T00:42:45.307 回答
1

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

更新:也许我对你的问题有误,同样的问题并通过 remove 解决ThreadEnforcer.ANY,你可以试试。

于 2014-08-07T02:44:43.540 回答