EventBus使用解决组件间通讯的一个开源项目,我们平时在使用GreenDao的时候,首页上也会看到它的身影,可以点击查看,下面就来看看如何使用这个简单实用的开源项目。因为考虑到月底了,这个月才写了一篇博客,所以,我可能根据EventBus的文档介绍分为几篇来写(虽然每一部分都比较简单,哈哈)
参考文档 上一篇: EventBus环境准备与使用 下一篇:EventBus的配置,黏性事件以及事件优先级
这一篇我们还是接着文档的顺序来看看EventBus中的几种线程模式的区别。
这部分的文档有一个整体的介绍如下:
EventBus can handle threading for you: events can be posted in threads different from the posting thread. A common use case is dealing with UI changes. In Android, UI changes must be done in the UI (main) thread. On the other hand, networking, or any time consuming task, must not run on the main thread. EventBus helps you to deal with those tasks and synchronize with the UI thread (without having to delve into thread transitions, using AsyncTask, etc).
In EventBus, you may define the thread that will call the event handling method by using one of the four ThreadModes.
这里我就不一一翻译了,大概的意思就是:
EventBus中提供了五种处理接收事件的线程模式,发布事件的线程和处理事件的线程不一定在一个线程中,你可以结合自己的业务选择不同的线程模式。
上面也说了,总共有五种线程模式,分别是:
Subscribers will be called in the same thread posting the event. This is the default. Event delivery is done synchronously and all subscribers will have been called once the posting is done. This ThreadMode implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for simple tasks that are known to complete is a very short time without requiring the main thread. Event handlers using this mode should return quickly to avoid blocking the posting thread, which may be the main thread.
大致意思:
订阅者的onEvent()处理事件的逻辑和发布事件逻辑所在的线程是同一个,避免了线程切换,主要用于耗时短的简单的且没有要求必须要在主线程中完成的任务。
Subscribers will be called in Android’s main thread (sometimes referred to as UI thread). If the posting thread is the main thread, event handler methods will be called directly (synchronously like described for ThreadMode.POSTING). Event handlers using this mode must return quickly to avoid blocking the main thread.
例如:
// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
log(event.message);
}
大致意思:
订阅者的onEvent()处理事件的逻辑在主线程(UI)中执行,所以逻辑不能耗时
例如:
// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
Subscribers will be called in Android’s main thread. The event is always enqueued for later delivery to subscribers, so the call to post will return immediately. This gives event processing a stricter and more consistent order (thus the name MAIN_ORDERED). For example if you post another event in an event handler with MAIN thread mode, the second event handler will finish before the first one (because it is called synchronously – compare it to a method call). With MAIN_ORDERED, the first event handler will finish, and then the second one will be invoked at a later point in time (as soon as the main thread has capacity).
Event handlers using this mode must return quickly to avoid blocking the main thread.
大致意思:
订阅者的onEvent()处理事件的逻辑和上一个模式一样都是在主线程执行,但是不同的点在于其是一个有序的执行过程(onEvent),不像前一个是同步执行的。
例如:
// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}
Subscribers will be called in a background thread. If posting thread is not the main thread, event handler methods will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single background thread that will deliver all its events sequentially. Event handlers using this mode should try to return quickly to avoid blocking the background thread.
大致意思:
订阅者的onEvent()处理事件的逻辑在一个后台线程执行(非主线程),如果发布事件的线程不是主线程,则订阅者的onEvent()处理事件的逻辑和发布事件的线程一样;如果发布事件的线程是主线程,那么订阅者的onEvent()处理事件的逻辑在单独的一个线程中执行
比如:
// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
saveToDisk(event.message);
}
Event handler methods are called in a separate thread. This is always independent from the posting thread and the main thread. Posting events never wait for event handler methods using this mode. Event handler methods should use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number of long running asynchronous handler methods at the same time to limit the number of concurrent threads. EventBus uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.
大致意思:
订阅者的onEvent()处理事件的逻辑在一个单独的线程中执行,发布事件从不等待使用此模式的事件处理程序方法。如果事件处理程序方法的执行是耗时操作,例如用于网络访问,则应使用此模式。为了避免同时触发大量长时间运行的异步处理程序方法来限制并发线程的数量。EventBus使用线程池来有效地重用已完成的异步事件处理程序中的线程。
比如:
// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
backend.send(event.message);
}
MainActivity.java代码:
package com.hfut.operationeventbus;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* @author why
* @date 2019-2-22 15:54:08
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivitytest";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.send_MsgEvent).setOnClickListener(this);
EventBus.getDefault().register(this);//订阅消息
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMsgEvent(MSGEvent event) {
Log.e(TAG, "ThreadMode.MAIN订阅者,线程为:" + Thread.currentThread().getName()+",发布者线程:"+event.getMsgInfo());
}
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMsgEventMain(MSGEvent event) {
Log.e(TAG, "ThreadMode.MAIN_ORDERED订阅者,线程为:" + Thread.currentThread().getName()+",发布者线程:"+event.getMsgInfo());
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMsgEventPosting(MSGEvent event) {
Log.e(TAG, "ThreadMode.POSTING订阅者,线程为:" + Thread.currentThread().getName()+",发布者线程:"+event.getMsgInfo());
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMsgEventAsync(MSGEvent event) {
Log.e(TAG, "ThreadMode.ASYNC订阅者,线程为:" + Thread.currentThread().getName()+",发布者线程:"+event.getMsgInfo());
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMsgEventBackground(MSGEvent event) {
Log.e(TAG, "ThreadMode.BACKGROUND订阅者,线程为:" + Thread.currentThread().getName()+",发布者线程:"+event.getMsgInfo());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send_MsgEvent:
startActivity(new Intent(MainActivity.this,PublisherActivity.class));
break;
}
}
}
PublisherActivity.java代码:
package com.hfut.operationeventbus;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import org.greenrobot.eventbus.EventBus;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author why
* @date 2019-2-27 16:37:11
*/
public class PublisherActivity extends AppCompatActivity {
private static final String TAG = "PublisherActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_publisher);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
EventBus.getDefault().postSticky(new MSGEvent(Thread.currentThread().getName()+"------post1"));
}
// }, 1000,2000);
}, 2000);
}
@Override
protected void onResume() {
super.onResume();
EventBus.getDefault().postSticky(new MSGEvent(Thread.currentThread().getName()+"------post2"));
}
}
日志结果:
如图所示,日志结果验证了上面的解释,在实际的使用中,一定要结合逻辑处理的不同(事件不同)采用不同的线程模式。
注:欢迎扫码关注