我刚刚开始查看GreenRobot的EventBus for Android,并对线程有疑问。
我有一个长时间运行的进程,我想在后台线程上运行,完成后会更新UI。
类似于:
public void onEventBackgroundThread(MyEvent event) {
doSomeLongRunningProcess();
updateUI();
}
显然updateUI()
不能在这里调用,因为它也会在后台运行。
那么推荐的处理方法是什么?在我的onEventBackgroundThread()
中触发另一个将在UI线程上运行的事件?或者从长时间运行的过程中解雇它?还是有更好的模式?
答案 0 :(得分:21)
当你得到结果时,我可能会发射另一个事件。
public void onEventBackgroundThread(MyEvent event) {
doSomeLongRunningProcess();
EventBus.getDefault().post(new MyEventResult());
}
请注意:reading the docs,您会发现:
BackgroundThread :将在后台线程中调用订阅者。如果 发布线程不是主线程,事件处理程序方法也是如此 直接在发布帖子中调用。如果发布帖子是 主线程, EventBus使用单个后台线程 按顺序提供所有活动。使用此模式的事件处理程序 应尽量快速返回以避免阻塞后台线程。
如果您花了很长时间使用此方法,其他EventBus回调将被延迟,这可能会转换为无响应的应用程序。
您可能想要使用onEventAsync:
异步:在单独的线程中调用事件处理程序方法。这是 始终独立于发布主题和主线程。 发布事件永远不会等待使用此模式的事件处理程序方法。 如果执行可能,事件处理程序方法应使用此模式 需要一些时间,例如用于网络访问。避免触发大 同时长时间运行的异步处理程序方法的数量 限制并发线程数。 EventBus使用线程池 从已完成的异步事件处理程序有效地重用线程 通知。
答案 1 :(得分:3)
我建议发起另一个由onEventMainThread
方法处理的事件。
如果接收方已经未注册(例如,由于销毁而未注册活动),这对updateUI
根本没有被调用产生了积极的影响。