文章列表:
- EventBus源码剖析(1) – 订阅注册与注销
- EventBus源码剖析(2) – EventBusBuilder
- EventBus源码剖析(3) – 线程模式
- EventBus源码剖析(4) – 订阅记录
- EventBus源码剖析(5) – Poster
前言
上期文章 EventBus源码剖析(1) – 注册与注销订阅 介绍了订阅者向 EventBus 进行注册和注销的操作,并涉及部分 EventBus 初始化逻辑。
在初始化逻辑中,很多功能都由本文将介绍的 EventBusBuilder 提供。一般使用默认 EventBusBuilder 对象,但 EventBus 贴心地提供了定制的能力,以便满足不同需求。
一、类签名
通过自定义参数构造 EventBus 实例,并能装载自定义的默认 EventBus 实例。前文 EventBus源码剖析(1) – 注册与注销订阅_3.2 基础构造 使用此实例,通过 EventBus.builder() 创建新 builder。
1
public class EventBusBuilder
二、数据成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 构造线程池为newCachedThreadPool,所有实例共享同一个静态线程池
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
boolean logSubscriberExceptions = true;
boolean logNoSubscriberMessages = true;
boolean sendSubscriberExceptionEvent = true;
boolean sendNoSubscriberEvent = true;
boolean throwSubscriberException;
boolean eventInheritance = true;
boolean ignoreGeneratedIndex;
boolean strictMethodVerification;
// 获取静态实例的线程池
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
List<Class<?>> skipMethodVerificationForClasses;
List<SubscriberInfoIndex> subscriberInfoIndexes;
Logger logger;
MainThreadSupport mainThreadSupport;
三、构造方法
默认构造方法
1
2
EventBusBuilder() {
}
四、成员方法
设置 logSubscriberExceptions 的参数值,默认为 true。表示是否记录订阅者抛出异常的日志。
1
2
3
4
public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {
this.logSubscriberExceptions = logSubscriberExceptions;
return this;
}
设置 logNoSubscriberMessages 的参数值,默认为true
1
2
3
4
public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {
this.logNoSubscriberMessages = logNoSubscriberMessages;
return this;
}
设置 sendSubscriberExceptionEvent 的参数值,默认为true
1
2
3
4
public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {
this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent;
return this;
}
设置 sendNoSubscriberEvent 的参数值,默认为true
1
2
3
4
public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {
this.sendNoSubscriberEvent = sendNoSubscriberEvent;
return this;
}
设置 throwSubscriberException 的参数值,当订阅者出现异常时不继续运行,默认为false。建议和 BuildConfig.DEBUG 一起使用,开发期间不会错过任何抛出的异常。
1
2
3
4
public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {
this.throwSubscriberException = throwSubscriberException;
return this;
}
设置 eventInheritance 的参数值,默认为true。EventBus源码剖析(1) – 注册与注销订阅_4.2 subscribe 小节后半部分代码注释,里面包含 eventInheritance 的具体作用。默认情况下,EventBus 考虑事件类的层级结构(父类的订阅者将收到通知)。
关闭此特性能提升事件投递性能,对一个直接继承 Object 的简单事件类来说,事件投递性能有20%的提升。对更复杂的事件层级,提升幅度超过20%。
不过需记住的是,事件投送一般只消耗应用很小部分的处理器时间片,除非发送事件的频率每秒数以千计。
1
2
3
4
public EventBusBuilder eventInheritance(boolean eventInheritance) {
this.eventInheritance = eventInheritance;
return this;
}
自定义线程池替换默认线程池实现,为事件分发服务提供异步后台线程池。一般没有必要修改。
1
2
3
4
public EventBusBuilder executorService(ExecutorService executorService) {
this.executorService = executorService;
return this;
}
方法名验证,验证以onEvent开头的方法避免拼写错误。使用此方法能排除指定订阅者类的检查,并关闭对使用修饰符 public、not static、not abstract 方法的检查。
1
2
3
4
5
6
7
8
public EventBusBuilder skipMethodVerificationFor(Class<?> clazz) {
if (skipMethodVerificationForClasses == null) {
skipMethodVerificationForClasses = new ArrayList<>();
}
// 存入的类不会受到检查
skipMethodVerificationForClasses.add(clazz);
return this;
}
设置 ignoreGeneratedIndex 的参数值,默认为false。即使已经存在已生成的索引,也强制使用反射。
1
2
3
4
public EventBusBuilder ignoreGeneratedIndex(boolean ignoreGeneratedIndex) {
this.ignoreGeneratedIndex = ignoreGeneratedIndex;
return this;
}
设置 strictMethodVerification 的参数值,默认为false。启用严格的方法验证。
1
2
3
4
public EventBusBuilder strictMethodVerification(boolean strictMethodVerification) {
this.strictMethodVerification = strictMethodVerification;
return this;
}
添加由 EventBus 注解处理器建立的索引,需要手动注入
1
2
3
4
5
6
7
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
if (subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
为 EventBus 所有日志事件指定日志处理器,默认所有日志由 android.util.Log 处理。
1
2
3
4
public EventBusBuilder logger(Logger logger) {
this.logger = logger;
return this;
}
获取 Logger
1
2
3
4
5
6
7
8
9
10
Logger getLogger() {
if (logger != null) {
return logger;
} else {
// also check main looper to see if we have "good" Android classes (not Stubs etc.)
return Logger.AndroidLogger.isAndroidLogAvailable() && getAndroidMainLooperOrNull() != null
? new Logger.AndroidLogger("EventBus") :
new Logger.SystemOutLogger();
}
}
获取 MainThreadSupport
1
2
3
4
5
6
7
8
9
10
11
12
MainThreadSupport getMainThreadSupport() {
if (mainThreadSupport != null) {
return mainThreadSupport;
} else if (Logger.AndroidLogger.isAndroidLogAvailable()) {
// 获取Android Looper
Object looperOrNull = getAndroidMainLooperOrNull();
return looperOrNull == null ? null :
new MainThreadSupport.AndroidHandlerMainThreadSupport((Looper) looperOrNull);
} else {
return null;
}
}
尝试获取Android主线程上的 Looper。Looper源码:Android源码系列(5) – Looper
1
2
3
4
5
6
7
8
Object getAndroidMainLooperOrNull() {
try {
return Looper.getMainLooper();
} catch (RuntimeException e) {
// 不是Android应用或应用功能不正常,导致找不到MainLooper,返回null
return null;
}
}
装载由 EventBus.getDefault() 返回的默认 EventBus 实例。
1
2
3
4
5
6
7
8
9
10
public EventBus installDefaultEventBus() {
synchronized (EventBus.class) {
if (EventBus.defaultInstance != null) {
throw new EventBusException("Default instance already exists." +
" It may be only set once before it's used the first time to ensure consistent behavior.");
}
EventBus.defaultInstance = build();
return EventBus.defaultInstance;
}
}
根据当前定义配置构建 EventBus 实例
1
2
3
public EventBus build() {
return new EventBus(this);
}
五、MainThreadSupport
获取“主”线程的接口。对 Android 来说是UI线程,其他类型的工程则根据需要设定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public interface MainThreadSupport {
boolean isMainThread();
Poster createPoster(EventBus eventBus);
// AndroidHandlerMainThreadSupport是内部类,实现外部接口MainThreadSupport
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;
// 指定Looper
public AndroidHandlerMainThreadSupport(Looper looper) {
this.looper = looper;
}
@Override
public boolean isMainThread() {
return looper == Looper.myLooper();
}
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, looper, 10);
}
}
}