EventBus3不同之处

EventBus3的几处变化

Posted by BY on July 13, 2018

介绍

订阅者的变化

在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......
}

订阅者