EventBus
简介
一款针对Android优化的发布/订阅事件总。
项目地址
https://github.com/greenrobot/EventBus
特点
- 简化了组件之间的传递消息,将发送者和接收者解耦,同时避免了依赖性和生命周期问题。
- 使你的代码更加简化
- 快
- 小(~50k)
- 在很多的app中使用
- 有高级功能,比如线程间传递,订阅优先级等
gradle配置
compile 'org.greenrobot:eventbus:3.0.0'
使用
定义事件
public static class MessageEvent { /* Additional fields if needed */ }
声明订阅者
声明你的订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
注册和注销订阅者
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
发送订阅者
EventBus.getDefault().post(new MessageEvent());
知识点
1.threadMod四种模式,默认是ThreadMode: POSTING
ThreadMode: MAIN ,事件的处理会在UI主线程中执行,不应处理耗时的事件。
ThreadMode: BACKGROUND , 事件的处理会在一个BackgroundPoster后台线程中执行,虽然是后台线程但是有个处理队列。当一个处理耗时事件时可能会处理阻塞的情况。
ThreadMode: POSTING ,事件的处理在和事件的发送在相同的进程。
ThreadMode: ASYNC ,每个事件都会创建一个线程。
2.priority优先级,默认是0
优先级高的先处理,前提是在同一个线程中。比例下面的代码就有可能优先级失效。
@Subscribe(priority=1,threadMode = ThreadMode.ASYNC)
public void onPriority1(MessageEvent event){
Logger.d("onEventData priority=1");
}
@Subscribe(priority=2,threadMode = ThreadMode.ASYNC)
public void onPriority2(MessageEvent event){
Logger.d("onEventData priority=2");
}
@Subscribe(priority=3,threadMode = ThreadMode.ASYNC)
public void onPriority3(MessageEvent event){
Logger.d("onEventData priority=3");
}
@Subscribe(priority=4,threadMode = ThreadMode.ASYNC)
public void onPriority4(MessageEvent event){
Logger.d("onEventData priority=4");
}
@Subscribe(priority=5,threadMode = ThreadMode.ASYNC)
public void onPriority5(MessageEvent event){
Logger.d("onEventData priority=5");
}
3.sticky粘性,默认是false
预发送广播,如果有订阅者直接接收广播,如果没有等有可以接收粘性广播的订阅者还是可以接收到广播,如果不取消掉会一直存在。
发送粘性广播
EventBus.getDefault().postSticky(new MessageEvent());
取消粘性广播
EventBus.getDefault().removeStickyEvent();
源代码分析
初始化设置
- EventBus.installDefaultEventBus():创建默认的EventBus,只能创建一次
- EventBuilder.addIndex():增加索引
- EventBuilder.eventInheritance():是否订阅父类中的方法,默认是true
- EventBuilder.executorService():设置线程池。
- EventBuilder.ignoreGeneratedIndex():忽略索引
- EventBuilder.logNoSubscriberMessages():打印没有订阅方法,默认是true
- EventBuilder.logSubscriberExceptions():打印订阅异常,默认true
- EventBuilder.sendNoSubscriberEvent():在没有订阅的情况下不发送,默认true
- EventBuilder.sendSubscriberExceptionEvent():发送订阅中的异常,默认false
- EventBuilder.skipMethodVerificationFor():忽略对该类的方法验证
- EventBuilder.strictMethodVerification():是否启用严格的方法检查
- EventBuilder.throwSubscriberException():是否抛出异常
初始化EventBus
EventBus的默认defaultInstance实例。
这里可以通过EventBusBuilder构建多个EventBus,而且构建的每个EventBus都是相互隔离的。
public class EventBus {
....
static volatile EventBus defaultInstance;
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
....
/** Convenience singleton for apps using a process-wide EventBus instance. */
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
/**
* Creates a new EventBus instance; each instance is a separate scope in which events are delivered. To use a
* central bus, consider {@link #getDefault()}.
*/
public EventBus() {
this(DEFAULT_BUILDER);
}
...
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
}
注册订阅者
EventBus:register()
||
||加载订阅方法
||
SubscriberMethodFinder:findSubscriberMethods()
||
||先获取方法缓存,然后判断是否强制反射获取订阅的方法遍历List<SubscriberMethod>
||
EventBus:subscribe()
||
||生成Subscription对象并对方法进行排序,如果是sticky对预发送广播进行处理
||
发送广播
EventBus:post()或者postSticky()
||
||发送广播,如果是sticky加入到stickyEvents列表中
||设置发送的isMainThread和isPosting,判断canceled
||
EventBus:postSingleEvent()
||
||检查是否关闭eventInheritance,这里关闭就不会去检查父类的方法,可以以提高速度,默认是开着的
||
EventBus:postSingleEventForEventType()
||
||获取订阅的方法发送广播
||
EventBus:postToSubscription()
||
||通过threadMode分别处理,直接调用方法或者进入相对应的队列中
||
EventBus:invokeSubscriber()
||
||调用方法
||