线程模式
EventBus支持订阅者方法在不同于发布事件所在线程的线程中被调用。你可以使用线程模式来指定调用订阅者方法的线程。EventBus总共支持5种线程模式:
- ThreadMode.POSTING
- 订阅者方法将在发布事件所在的线程中被调用。也就是发送消息在那个线程,接收消息就在那个线程,比如发送消息在主线程中,接收消息则也在主线中执行,发送消息在子线程中,接收消息则也在相同的子线程中执行
- 这是 默认的线程模式。
- 事件的传递是同步的,一旦发布事件,所有该模式的订阅者方法都将被调用。
- 这种线程模式意味着最少的性能开销,因为它避免了线程的切换。因此,对于不要求是主线程并且耗时很短的简单任务推荐使用该模式。
- 使用该模式的订阅者方法应该快速返回,以避免阻塞发布事件的线程,这可能是主线程。
- ThreadMode.MAIN
- 订阅者方法将在主线程(UI线程)中被调用。
- 可以在该模式的订阅者方法中直接更新UI界面。
- 如果发布事件的线程是主线程,那么该模式的订阅者方法将被直接调用。
- 使用该模式的订阅者方法必须快速返回,不应该做耗时的操作,以避免阻塞主线程。
- ThreadMode.MAIN_ORDERED
- 订阅者方法将在主线程(UI线程)中被调用。
- 可以在该模式的订阅者方法中直接更新UI界面。
- 事件将先进入队列然后才发送给订阅者,所以发布事件的调用将立即返回
- 使用该模式的订阅者方法必须快速返回,不应该做耗时的操作,以避免阻塞主线程。
- 不同的线程发送消息,先加入队列的会优先执行
- ThreadMode.BACKGROUND
- 订阅者方法将在后台线程中被调用。
- 如果发布事件的线程不是主线程,那么订阅者方法将直接在该线程中被调用。
- 如果发布事件的线程是主线程,那么将使用一个单独的后台线程,该线程将按顺序发送所有的事件。
- 使用该模式的订阅者方法应该快速返回,以避免阻塞后台线程。
- ThreadMode.ASYNC
- 订阅者方法将在一个子线程中被调用。
- 发布事件的调用将立即返回。
- 该模式适合订阅者方法执行耗时操作,例如网络访问
- 避免触发大量的长时间运行的订阅者方法,以限制并发线程的数量。
- EventBus使用了一个线程池来有效地重用已经完成调用订阅者方法的线程。
不同线程模式的使用
ThreadMode.POSTING
A:ThreadMode: POSTING-->主线程中发送
//ThreadMode: POSTING-->主线程中发送
String postting_main_msg
= "MessageEvent is from ThreadMode POSTING:on mainThread";
post(new PostingMessageEvent(postting_main_msg));
B:ThreadMode: POSTING-->子线程中发送
//ThreadMode: POSTING-->子线程中发送
new Thread(new Runnable() {
@Override
public void run() {
String postting_thread_msg = "MessageEvent is from ThreadMode POSTING:on asynchronous";
post(new PostingMessageEvent(postting_thread_msg));
}
}).start();
订阅者接收消息
//发送消息在什么线程,接收消息就在什么线程
@Subscribe(threadMode = ThreadMode.POSTING)
public void onEventThreadModePosting(MessageEvent event) {
final String str = logMessage(event);
if (UIUtils.isMainThread()) {
tvMode.setText(str);
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvMode.setText(str);
}
});
}
}
ThreadMode.MAIN
ThreadMode: MAIN-->子线程中发送
//ThreadMode: MAIN-->子线程中发送
new Thread(new Runnable() {
@Override
public void run() {
String postting_thread_msg
= "MessageEvent is from ThreadMode MAIN:on asynchronous";
post(newMainMessageEvent(postting_thread_msg));
}
}).start();
订阅者接收消息
//无论发送消息在什么线程,接收消息都在主线程
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventThreadModeMain(MainMessageEvent event) {
final String str = logMessage(event);
if (UIUtils.isMainThread()) {
tvMode.setText(str);
}
}
ThreadMode.ASYNC
ThreadMode: Async-->主线程中发送
//ThreadMode: Async-->主线程中发送
String async_main_msg
= "MessageEvent is from ThreadMode Async:on MAIN";
post(new AsyncMessageEvent(async_main_msg));
ThreadMode: Async-->子线程中发送
//ThreadMode: Async-->子线程中发送
new Thread(new Runnable() {
@Override
public void run() {
String postting_thread_msg = "MessageEvent is from ThreadMode Async:on asynchronous";
post(new AsyncMessageEvent(postting_thread_msg));
}
}).start();
订阅者接收消息
//无论发送消息在什么线程,接收消息都在新开辟的子线程中执行
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onEventThreadModeASYNC(AsyncMessageEvent event) {
final String str = logMessage(event);
if (UIUtils.isMainThread()) {
tvMode.setText(str);
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvMode.setText(str);
}
});
}
}
ThreadMode.BACKGROUND
ThreadMode.BACKGROUND-->主线程中发送
//ThreadMode.BACKGROUND-->主线程中发送
String background_main_msg = "MessageEvent is from ThreadMode background:on MAIN";
post(new BackgroundMessageEvent(background_main_msg));
ThreadMode.BACKGROUND-->子线程中发送
//ThreadMode.BACKGROUND-->子线程中发送
new Thread(new Runnable() {
@Override
public void run() {
String btn_background_thread_msg = "MessageEvent is from ThreadMode background:on asynchronous";
post(new BackgroundMessageEvent(btn_background_thread_msg));
}
}).start();
订阅者接收消息
//如果发送消息在主线程,接收消息都在新开辟的子线程中执行,
//如果发送消息在子线程,接收消息和发送消息在相同的线程.
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEventThreadModeBackground(BackgroundMessageEvent event) {
final String str = logMessage(event);
if (UIUtils.isMainThread()) {
tvMode.setText(str);
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvMode.setText(str);
}
});
}
}
ThreadMode.MAIN_ORDERED
ThreadMode: MAIN_ORDERED-->单线程中发送
//ThreadMode: MAIN_ORDERED-->单线程中发送
String btn_background_thread_msg = "MessageEvent is from ThreadMode MAIN_ORDERED:on MAIN";
post(new OrderedMessageEvent(btn_background_thread_msg));
String btn_background_thread_msg1 = "MessageEvent1 is from ThreadMode MAIN_ORDERED:on MAIN";
post(new OrderedMessageEvent(btn_background_thread_msg1));
String btn_background_thread_msg2 = "MessageEvent2 is from ThreadMode MAIN_ORDERED:on MAIN";
post(new OrderedMessageEvent(btn_background_thread_msg2));
ThreadMode: MAIN_ORDERED-->多线程中发送
//ThreadMode: MAIN_ORDERED-->多线程中发送
for (int i = 0; i < 6; i++) {
final String msg = "MessageEvent is from ThreadMode MAIN_ORDERED:on more thread-->" + i;
new Thread(new Runnable() {
@Override
public void run() {
post(new OrderedMessageEvent(msg));
}
}).start();
订阅者接收消息
//先发消息先处理,处理在主线程执行.
//如果发送消息在不同的异步线程,那么先加入队列先处理.
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onEventThreadModeMAIN_ORDERED(OrderedMessageEvent event) {
final String str = logMessage(event);
if (UIUtils.isMainThread()) {
tvMode.setText(str);
}
}
demo地址
demo源码