深入理解 EventBus 3.0 之源码分析
EventBus 3.0 从使用到源码分析
EventBus 解决了什么问题
EventBus 的思想
EventBus 的编译时注解
EventBus 用到的设计模式
值得学习的细节
不足之处
感悟
创建一个回调接口,在接口中定义监听到事件发生时要进行的操作
需要监听的地方创建一个回调的具体实现,然后传递给事件触发者
事件触发者持有回调接口的引用,在事件发生时,调用回调接口的具体实现
将运行时需要进行的查找工作转移到编译时
使用哈希表保存查找到的信息
生成的类实现约定的接口,便于运行时调用
static volatile EventBus defaultInstance;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
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;
}
private final HandlerPoster mainThreadPoster;
private final BackgroundPoster backgroundPoster;
private final AsyncPoster asyncPoster;
提供默认 Builder 和默认实例
选用合适的线程池
Executors.newCachedThreadPool()
适合并发执行大量短期的小任务
使用 ThreadLocal
实现事件队列的线程无关性
并发控制
数据有可能在操作的同时添加,使用 CopyOnWriteArrayList
与 synchronized
职责分离
查找类中的订阅方法有专门的类 SubscriberMethodFinder
保存类与其中的订阅方法关系有专门的类 Subscription
不同线程发送事件也有专门的类
使用 map 缓存一些可能会重复使用的信息
事件与其的父类和接口的映射 Map
事件与对应的订阅者关联列表 Map
订阅者与订阅的事件关联列表 Map
保存粘性事件 Map
如果需要创建大量相同类型的对象,考虑使用对象池,对象使用完毕回收,只要把引用其他对象置为 null 即可
FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE]
List
将重复传递的一些参数封到一个对象里传递
PostingThreadState
创建了自己的事件队列 PendingPostQueue
双向链表
生产者-消费者模型, 出队 wait - 入队 nofityAll
EventBus mInstance = EventBus.builder()
.addIndex(new MyEventBusIndex())
.build();
在程序比较简单时是比较灵活,但是当程序比较复杂时很容易造成程序流程的混乱
非编写本人,其他人看程序不那么容易理解
调试程序的过程也会变得很困难。