意图服务发布的Otto事件订阅/接收问题

5

我似乎遇到了两个问题之一。要么是出现以下错误:

java.lang.IllegalStateException: Event bus [Bus "default"] accessed from non-main thread Looper

如果我已经“解决”了这个问题,那么我就不会在我的订阅者中收到事件。

目前,我有一个类,由几个源码拼凑而成,它是 Bus 的子类:

public class MainThreadBus extends Bus {
    private static Bus _bus;
    private Handler _handler = new Handler(Looper.getMainLooper());

    public MainThreadBus() {
        if (_bus == null) {
            _bus = new Bus();
        }
    }

    @Override public void register(Object obj) {
        _bus.register(obj);
    }

    @Override public void unregister(Object obj) {
        _bus.unregister(obj);
    }

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

这是在活动中使用的代码:

Which is used in an Activity like this:

@Subscribe
public void requestProgressAvailable(RESTRequestProgress progress) {
    processProgress(progress);
}

@Override
protected void onResume() {
    super.onResume();

    _bus = new MainThreadBus();
    _bus.register(this);
}

@Override
protected void onPause() {
    super.onPause();

    _bus = new MainThreadBus();
    _bus.unregister(this);
}

像这样从IntentService发布:

_bus = new MainThreadBus();
_bus.post(request.createRESTRequestProgress(RESTRequest.STATUS_STARTED));

消息未被接收。由于备用配置导致我收到线程错误,因此现在我采用这种方式。

那么,我错过了什么,或者做错了什么?

编辑:感谢下面的Andy指出我的代码并非我所想象的那样。上面的代码现在反映了基于该反馈进行的修改。


我已经重新使用了greenrobot EventBus进行实现,目前它正常工作。但我仍然对Otto解决方案感兴趣。 - Michael
2个回答

8

除了这个实现不是单例模式之外,在遇到这个错误时,您可以在构造函数中使用threadEnforcer.ANY选项:

private static final Bus BUS = new Bus(ThreadEnforcer.ANY);

3
问题在于你的代码没有与同一个总线实例交互。你应该访问同一个总线,而不是在每种情况下创建一个新的MainThreadBus,例如可以从工厂或通过注入获取单例。

我之前以为我的代码使用了一个静态的_bus,并且只设置了一次,但显然不是这样。我已经修改了上面的代码以反映一种新的方法,但仍然没有起作用。 - Michael

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