EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent、Handler、BroadCast在Fragment、Activity、Service、线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。EventBus在GitHub上的开源库地址,刚开始使用的可以看一下,GitHub上有最基本的使用方法。
EventBus引用
最基本的引用如下:
compile 'org.greenrobot:eventbus:3.1.1'
添加这个引用之后就可以使用EventBus了,但是EventBus更新3.1.1之后采用了注解的方式,接收的函数名可以自定义,但是传递效率就不是很高了,因此需要加速处理,当然,也可以不使用注解和加速,加速引用如下:
//defaultConfig 下加入代码
defaultConfig{
javaCompileOptions {
annotationProcessorOptions {
arguments = [eventBusIndex: 'com.yz.ui.fragmentdemo.MyEventBusIndex']
}
}
}
//dependencies 下加入代码
dependencies{
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
注意:javaCompileOptions这里是生成加速配置文件,MyEventBusIndex就是生成文件的名字,前面就是你的包名,编译之后可以查看:
EventBus配置
这一步骤没有也一样可以使用,只是有一些需求可以在这里配置,如:加速、设置debug模式下要抛出异常等
//修改默认实现的配置,记住,必须在第一次EventBus.getDefault()之前配置,且只能设置一次。建议在application.onCreate()调用
EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).addIndex(new MyEventBusIndex()).installDefaultEventBus();
// 这样每次获取到默认实例,都是使用Subscriber Index的了,代码得到了精简。
EventBus eventBus = EventBus.getDefault();
EventBus使用
定义EventBus事件类
public class MessageEvent {
private Object msg;
public MessageEvent(Object msg) {
this.msg = msg;
}
public Object getMsg() {
return msg;
}
public void setMsg(Object msg) {
this.msg = msg;
}
@Override
public String toString() {
return "MessageEvent{" +
"msg=" + msg +
'}';
}
}
注意:这里我是用Object类型是为了传递各种类型的数据,使这个事件类变成通用的事件类,如果你的事件需要同时存在可在该类中加入一个标识来区别自己的事件。
注册/注销EventBus
EventBus.getDefault().register(this);//注册
EventBus.getDefault().unregister(this);//注销
注意:官方是推荐将注册写到onStart,将注销写到onStop中,当然你也可以更具自己的需求来改变的
发布订阅事件
- 普通的事件发送
EventBus.getDefault().post(new MessageEvent("发送事件"));
注意:EventBus是为了给已经存在的窗体传递信息,而且订阅者必须要注册且不能被注销了,否则接收不到消息
- 粘性的事件发送
EventBus.getDefault().postSticky(new MessageEvent("发送粘性事件"));
注意:粘性的事件发送后只要不取消会一直存在
订阅事件处理
在接收数据需要处理事件的窗体中定义订阅事件处理函数:
@Subscribe(threadMode = ThreadMode.POSTING, priority = 2, sticky = true)
public void onMessageEventPost(MessageEvent data) {
}
注意:threadMode指线程模式,priority指事件的优先级,sticky是否是粘性事件
- threadMode 线程模式有四种:NAIN UI主线程、BACKGROUND 后台线程、POSTING 和发布者处在同一个线程、ASYNC 异步线程 不写注解默认为POSTING模式,具体介绍 threadMode
- priority 其实和Boardcast接收者的优先级差不多,数越大优先级越高,一般0-100。默认为0
- sticky 在注册期间,所有粘性订户方法将立即获得之前发布的粘性事件
删除事件
- 普通事件删除
EventBus.getDefault().cancelEventDelivery(event);
注意:事件取消仅限于ThreadMode.PostThread下才可以使用
- 粘性事件删除
//指定粘性事件删除 T stickyEvent = EventBus.getDefault().getStickyEvent(eventType); if (stickyEvent != null) { EventBus.getDefault().removeStickyEvent(stickyEvent); } //删除所有粘性事件 EventBus.getDefault().removeAllStickyEvents();
EventBus封装工具类如下:
/**
* 残梦 EventBus事件处理
* <p>
* EventBus是为了给已经存在的窗体传递信息,而且订阅者必须要注册且不能被注销了,否则接收不到消息
* 给还未创建的窗体传递信息需要用粘性事件
* <p>
* Created by dell on 2018/1/26.
*/
public class EventBusUtils {
private static final String TAG = EventBusUtils.class.getSimpleName();
/**
* 控制日志在开发的时候输出,发布的时候不输出,在开发的时候错误崩溃,而发布的时候不崩溃
* 打开加速
*/
public static void openIndex() {
//修改默认实现的配置,记住,必须在第一次EventBus.getDefault()之前配置,且只能设置一次。建议在application.onCreate()调用
EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).addIndex(new MyEventBusIndex()).installDefaultEventBus();
// 这样每次获取到默认实例,都是使用Subscriber Index的了,代码得到了精简。
EventBus eventBus = EventBus.getDefault();
}
/**
* 注册EventBus
*
* @param subscriber 订阅者
*/
public static void register(Object subscriber) {
if (!EventBus.getDefault().isRegistered(subscriber)) {
EventBus.getDefault().register(subscriber);
}
}
/**
* 注消EventBus
*
* @param subscriber 订阅者
*/
public static void unregister(Object subscriber) {
EventBus.getDefault().unregister(subscriber);
}
/**
* 发布订阅事件
*
* @param Publisher 发布者
*/
public static void post(Object Publisher) {
EventBus.getDefault().post(Publisher);
}
/**
* 发布粘性订阅事件
*
* @param Publisher 发布者
*/
public static void postSticky(Object Publisher) {
EventBus.getDefault().postSticky(Publisher);
}
/**
* 移除指定的粘性订阅事件
*
* @param eventType 移除的内容
* @param <T>
*/
public static <T> void removeStickyEvent(Class<T> eventType) {
T stickyEvent = EventBus.getDefault().getStickyEvent(eventType);
if (stickyEvent != null) {
EventBus.getDefault().removeStickyEvent(stickyEvent);
}
}
/**
* 取消事件传送 事件取消仅限于ThreadMode.PostThread下才可以使用
* 不取消事件就会一直存在
*
* @param event
*/
public static void cancelEventDelivery(Object event) {
EventBus.getDefault().cancelEventDelivery(event);
}
/**
* 移除所有的粘性订阅事件
*/
public static void removeAllStickyEvents() {
EventBus.getDefault().removeAllStickyEvents();
}