58

简单BusProvider.getInstance().post()不带异常main thread。如何使用 Otto 事件总线将事件从服务发送到活动?

4

7 回答 7

122

要从任何线程(主线程或后台)发布并在主线程上接收,请尝试类似

public class MainThreadBus extends Bus {
  private final Handler mHandler = new Handler(Looper.getMainLooper());

  @Override
  public void post(final Object event) {
    if (Looper.myLooper() == Looper.getMainLooper()) {
      super.post(event);
    } else {
      mHandler.post(new Runnable() {
        @Override
        public void run() {
          MainThreadBus.super.post(event);
        }
      });
    }
  }
}

注意:一般方法要归功于 Jake Wharton 和https://github.com/square/otto/issues/38上的“pommedeterresaute” 。我只是用包装类而不是子类来实现它。

于 2013-03-15T13:09:29.700 回答
20

要从任何线程(主线程或后台)发布并在主线程上接收,请使用以下内容MainThreadBus而不是原版Bus

public class MainThreadBus extends Bus {
     private final Handler handler = new Handler(Looper.getMainLooper());

     @Override public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    MainThreadBus.super.post(event);
                }
            });
        }
    }
}

这是基于安迪丹尼的回答。

没有必要同时扩展和包装一个Bus对象,做一个或另一个。在丹尼的回答中,它实际上是一个包装器,Bus基类只是像接口一样被使用,所有的功能都被覆盖了。

即使您删除了Bus基类,它也会起作用,除非您碰巧MainThreadBus通过Bus引用引用了。

于 2014-02-27T09:13:50.590 回答
3

或者,如果您确定您是从非主线程发布的,则只需执行此操作:

new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        mBus.post(new myEvent());
                    }
                });
于 2016-11-25T04:06:19.427 回答
2

总线 = 新总线(ThreadEnforcer.ANY);是这个问题的明确解决方案。它的所有你必须做的。

于 2016-04-04T10:55:41.707 回答
0

对我来说最好的实现自定义总线类

public class AndroidBus extends Bus {
    private final Handler mainThread = new Handler(Looper.getMainLooper());

    @Override
    public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            mainThread.post(() -> AndroidBus.super.post(event));
        }
    }
}
于 2016-04-14T10:31:35.660 回答
0

我做的很简单:

Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                bus.post(event);
            }

        });
于 2017-01-19T14:01:24.630 回答
-1

只需创建BasicBuswithThreadEnforcer.NONE即可从非主线程发布事件。提到ThreadEnforcer.MAIN的是完全相反(和默认),它只接受来自主线程的帖子。

于 2015-04-22T21:55:15.767 回答