介绍
订阅者的变化
在EventBus3中订阅者的方法可以随意取,而不用像EventBus2中要以onEvent开头。
首先需要分析Subscribe的注解:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
//线程模式,订阅者在哪个线程接收到事件
ThreadMode threadMode() default ThreadMode.POSTING;
//是否是粘性事件
boolean sticky() default false;
//优先级,默认为0
int priority() default 0;
}
ThreadMode 是枚举:
public enum ThreadMode {
POSTING, //post的时候是哪个线程订阅者就在哪个线程接收到事件
MAIN, //订阅者在主线程接收到事件
BACKGROUND, //订阅者在主线程接收到消息,如果post的时候不是在主线程的话,那么订阅者会在post的时候那个线程接收到事件。适合密集或者耗时少的事件。
ASYNC //订阅者会在不同的子线程中收到事件。适合操作耗时的事件。
}
在使用时全部参数都用的例子:
@Subscribe(threadMode = ThreadMode.MAIN, sticky = false, priority = 2)
public void handleSomethingElse(SomeOtherEvent event){
doSomethingWith(event);
}
注册订阅者
public void register(Object subscriber) {
//拿到订阅者的class
Class<?> subscriberClass = subscriber.getClass();
//通过class去找到订阅方法
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
//blablabla...
}
我们先看SubscriberMethodFinder类的findSubscriberMethods()方法:
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//先从METHOD_CACHE中查看是否已经有这个订阅者了
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
//有了的话直接把订阅者的方法返回
if (subscriberMethods != null) {
return subscriberMethods;
}
//ignoreGeneratedIndex默认是false
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
//放到缓存当中
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
在使用 EventBus.getDefault() 时用的是默认的 builder ,而当使用 EventBusBuilder.installDefaultEventBus() 时是设置自己可配置的 builder 。这里我们先讨论默认情况下的。所以应该走到 findUsingInfo(subscriberClass) 方法来。
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
//1.得到一个FindState对象
FindState findState = prepareFindState();
//blablabla......
}