简介
EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递,这里的事件可以理解为消息。EventBus 3.0中EventBus提供了EventBusAnnotationProcessor注解处理器来在编译期通过读取@Subscribe()注解并解析、处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息,这样就比在EventBus 2.x 采用反射的方式对整个注册的类的所有方法进行扫描来完成注册的速度要快
使用
首先添加引用 compile 'org.greenrobot:eventbus:3.0.0'
EventBus的主要元素
- Event :事件,可以是任意类型的对象。
- Publisher:事件发布者,用于通知Subscriber有事件发生
- Subscriber :事件订阅者,接收特定的事件
-
ThreadMode :定义函数在何种线程中执行,主要包含四个ThreadMode
- ThreadMode.POSTING: 事件的处理在和事件的发送在相同的进程,所以事件处理时间不应太长,不然影响事件的发送线程,而这个线程可能是UI线程。
- ThreadMode.MAIN: 事件的处理会在UI线程中执行。事件处理时间不能太长,这个不用说的,长了会ANR的。
- ThreadMode.BACKGROUND: 事件的处理会在一个后台线程中执行,但事件处理时间还是不应该太长,因为如果发送事件的线程是后台线程,会直接执行事件,如果当前线程是UI线程,事件会被加到一个队列中,由一个线程依次处理这些事件,如果某个事件处理时间太长,会阻塞后面的事件的派发或处理。
- ThreadMode.AYSNC: 事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程(有线程池),但最好限制线程的数目。
使用的基本步骤
- 定义事件类型:
public class Event {}
- 定义事件处理方法:
public void onEvent
- 注册订阅者:
EventBus.getDefault().register(this)
- 发送事件:
EventBus.getDefault().post(new Event())
- 取消注册:
EventBus.getDefault().unregister(this)
如下一个使用例子
- 定义一个事件类型
public class Event {
private String message;
public Event(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
- 处理事件
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注册
EventBus.getDefault().register(this);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
Log.e("lwd", "hahha");
startActivity(intent);
}
});
}
/**
* 在这里处理事件
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 100)//在ui线程执行 优先级100
public void onEvent(Event event) {
String msg = event.getMessage();
((TextView) findViewById(R.id.tv)).setText(msg);
}
@Override
protected void onDestroy() {
super.onDestroy();
//反注册
EventBus.getDefault().unregister(this);
}
}
优先级越高优先获得消息,优先级高的订阅者可以终止事件往下传递
EventBus.getDefault().cancelEventDelivery(event) ;
其中sticky=true
表示黏性事件,为了方便理解成订阅在发布事件之后,但同样可以收到事件。发送粘性事件EventBus.getDefault().postSticky(new Event());
如果不再需要该粘性事件我们可以移除EventBus.getDefault().removeStickyEvent(new DataSynEvent());
,或者调用移除所有粘性事件EventBus.getDefault().removeAllStickyEvents();
- 发送事件
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new Event("hahahaha"));
}
}).start();
}
});
}
}
调用不同的订阅函数
首先建立四个类:FirstEvent、SecondEvent、ThirdEvent 、FourthEvent。
public class FirstEvent {
private String message;
public FirstEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public class SecondEvent{
private String message;
public SecondEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public class ThirdEvent{
private String message;
public ThirdEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
public class FourthEvent{
private String message;
public FourthEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
然后在MainActivity中,增加四种模式的订阅函数
/**
* 在这里处理事件
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN, priority = 100)
public void onEventMain(FirstEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
@Subscribe(threadMode = ThreadMode.BACKGROUND, priority = 100)
public void onEventBackground(SecondEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
@Subscribe(threadMode = ThreadMode.POSTING, priority = 100)
public void onEventPosting(ThirdEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
@Subscribe(threadMode = ThreadMode.ASYNC, priority = 100)
public void onEventAsync(FourthEvent event) {
String msg = event.getMessage();
Log.e("lwd", msg);
}
接下来在SecondActivity中增加四个按钮,分别发送不同类别的事件
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new FirstEvent("我是1"));
}
}).start();
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new SecondEvent("我是2"));
}
}).start();
}
});
findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new ThirdEvent("我是3"));
}
}).start();
}
});
findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new FourthEvent("我是4"));
}
}).start();
}
});
分别顺序点击SecondActivity的四个按钮,打印信息如下:
10-18 11:18:47.723 10159-10159/com.example.luoweidong.eventbu E/lwd: 我是1
10-18 11:18:48.763 10159-10262/com.example.luoweidong.eventbu E/lwd: 我是2
10-18 11:18:49.863 10159-10281/com.example.luoweidong.eventbu E/lwd: 我是3
10-18 11:18:50.403 10159-10294/com.example.luoweidong.eventbu E/lwd: 我是4
由此可见,通过发布不同的事件类的实例,EventBus根据类的实例分别调用了不同的订阅函数来处理事件。订阅函数的执行是根据参数中的事件类的类名来决定的。