概念
EventBus是一种用于Android的事件发布-订阅的事件总线。由三个角色构成:Publisher(发布者)、Event(事件)和Subscriber(订阅者)。
线程模型
- POSTING:默认,表示事件处理函数的线程跟发布事件的线程在同一个线程。
- MAIN:表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
- BACKGROUND:表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
- ASYNC:表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。
源码
getDefault()
//双重校验并加锁的单例模式创建EventBus实例。
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();/** EventBus无参构造函数 */
}
}
}
return defaultInstance;
}
- EventBus无参构造函数:
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();/** EventBusBuilder构造函数 */
public EventBus() {
this(DEFAULT_BUILDER); /** EventBus有参构造函数 */
}
- EventBusBuilder构造函数:
EventBusBuilder() {
}
- EventBus有参构造函数:
//同时创建一个EventBusBuilder对象对EventBus进行初始化。
//其中有三个比较重要的集合和一个SubscriberMethodFinder对象。
EventBus(EventBusBuilder builder) {
logger = builder.getLogger();
subscriptionsByEventType = new HashMap<>();//事件订阅类型集合一😊
typesBySubscriber = new HashMap<>();//订阅者类型的集合😊
stickyEvents = new ConcurrentHashMap<>();//联系集合😊
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;//主线程初始化操作
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;//执行者服务
}
regist()
public void register(Object subscriber) {
//首先通过反射获取到订阅者的Class对象。
Class<?> subscriberClass = subscriber.getClass();
//通过SubscriberMethodFinder对象获取订阅者中所有订阅的事件集合。
//它先从缓存中获取,如果缓存中有,直接返回;
//如果缓存中没有,通过反射的方式去遍历订阅者内部被注解的方法,将这些方法放入到集合中进行返回。
List<SubscriberMethod> subscriberMethods = /** SubscriberMethod类源码 */
subscriberMethodFinder.findSubscriberMethods(subscriberClass); /** findSubscriberMethods()方法获取订阅者中所有订阅的事件集合 */
//同步操作,遍历获取的集合,将订阅者和事件进行绑定。
//在绑定之后会判断绑定的事件是否是粘性事件,
//如果是粘性事件,直接调用postToSubscription方法,将之前发送的粘性事件发送给订阅者。
//其实这也很好理解,如果在粘性事件发送之前注册的订阅者,当发送粘性事件时,会接收到该事件;
//如果是粘性事件发送之后注册的订阅者,同样也能接收到事件。
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);/** subscribe()方法绑定订阅者和事件 */
}
}
}
- findSubscriberMethods()方法获取订阅者中所有订阅的事件集合
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//首先从缓存中读取
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//是否忽略注解器生成的MyEventBusIndex类
if (ignoreGeneratedIndex) {
//利用反射来获取订阅类中的订阅方法信息
subscriberMethods = findUsingReflection(subscriberClass);
} else {
//从注解器生成的MyEventBusIndex类中获得订阅类的订阅方法信息
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;
}
}
- SubscriberMethod类源码:
public class SubscriberMethod {
final Method method;//方法
final ThreadMode threadMode;//执行线程
final Class<?> eventType;//接收的事件类型
final int priority;//优先级
final boolean sticky;
/** Used for efficient comparison */
String methodString;
}
- subscribe()方法绑定订阅者和事件:
//参数:订阅者,订阅方法集
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//获取订阅方法的参数类型
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//根据订阅的事件类型获取所有的订阅者
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
//将订阅者添加到subscriptionsByEventType集合中
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
//根据优先级,将订阅者插入到指定的位置
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
//获取订阅者所有订阅的事件类型
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
//将该事件类型添加到typesBySubscriber中
subscribedEvents.add(eventType);
//如果接收sticky事件,立即分发sticky事件
if (subscriberMethod.sticky) {
if (eventInheritance) {
// Existing sticky events of all subclasses of eventType have to be considered.
// Note: Iterating over all events may be inefficient with lots of sticky events,
// thus data structure should be changed to allow a more efficient lookup
// (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}