11

我刚刚开始查看 GreenRobot 的Android 的EventBus并且对线程有疑问。

我有一个长时间运行的进程,我想在后台线程上运行,完成后会更新 UI。

所以像:

public void onEventBackgroundThread(MyEvent event) {
        doSomeLongRunningProcess();
        updateUI();
    }

显然updateUI()不能在这里调用,因为它也会在后台运行。

那么处理这个问题的推荐方法是什么?从我的内部触发另一个onEventBackgroundThread()将在 UI 线程上运行的事件?还是从长期运行的过程本身中触发它?还是有更好的模式?

4

2 回答 2

20

当你得到结果时,我可能会触发另一个事件。

public void onEventBackgroundThread(MyEvent event) {
    doSomeLongRunningProcess();
    EventBus.getDefault().post(new MyEventResult());
}

但请注意阅读文档,您会发现:

BackgroundThread:订阅者将在后台线程中调用。如果发布线程不是主线程,则事件处理方法将直接在发布线程中调用。如果发布线程是主线程,EventBus 使用单个后台线程,将按顺序传递其所有事件。使用此模式的事件处理程序应尽量快速返回以避免阻塞后台线程。

如果您在此方法中花费很长时间,其他 EventBus 回调将被延迟,这可能会转化为无响应的应用程序。

您可能想使用 onEventAsync:

Async:事件处理程序方法在单独的线程中调用。这始终独立于发布线程和主线程。发布事件从不等待使用此模式的事件处理程序方法。如果它们的执行可能需要一些时间,例如网络访问,事件处理程序方法应该使用这种模式。避免同时触发大量长时间运行的异步处理程序方法,以限制并发线程数。EventBus 使用线程池从已完成的异步事件处理程序通知中有效地重用线程。

于 2013-06-06T12:58:01.653 回答
3

我建议触发另一个将由onEventMainThread方法处理的事件。

updateUI如果接收者已经未注册(例如,活动未注册,因为它已被销毁),这将产生根本不被调用的积极影响。

于 2013-06-06T12:28:45.730 回答