基本使用
//注册EventBus
EventBus.getDefault().register(this);
//发送事件
EventBus.getDefault().post(new FirstEvent("nihao-->"));
//接受事件回调方法
@Subscribe
public void onMainEvent(FirstEvent eventBean)
{
Toast.makeText(this,"FirstEvent--> "+eventBean.msg,Toast.LENGTH_SHORT).show();
Log.d(TAG,"FirstEvent ");
}
//反注册EventBus
EventBus.getDefault().unregister(this);
源码分析
//DCL 获取EventBus单例
public static EventBus getDefault()
{
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
//eventTypesCache 以eventType 为key,该类的接口与继承父类为value,主要是为了将所有关联的事件关系保存在表里面,进行事件继承的消息通知
private static final Map<Class<?>, List<Class<?>>> eventTypesCache = new HashMap<>();
//以事件类型为 key ,订阅列表 Subscription为value的一张map,
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
//以订阅者Subscriber 为key,以事件列表为value的map表
private final Map<Object, List<Class<?>>> typesBySubscriber;
//粘贴性事件表
private final Map<Class<?>, Object> stickyEvents;
public EventBus()
{
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder)
{
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
//主线程 post
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
//后台线程 post
backgroundPoster = new BackgroundPoster(this);
//异步线程 post
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;
}
** EventBus#register 注销方法 **
//看看比较重要的注册方法
public void register(Object subscriber)
{
//得到订阅者的类
Class<?> subscriberClass = subscriber.getClass();
//从subscriberMethodFinder集合里面去查找订阅该类里面的方法
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
//遍历进行订阅
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
** EventBus#subscribe **
// Must be called in synchronized block
//这里其实就是通过类型EventType 放 Subscription 集合
// 通过 subscriber 放类型 EventType 集合
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod)
{
Class<?> eventType = subscriberMethod.eventType;
//Subscription二次封装了订阅者对象和 subscriberMethod,并且put到 CopyOnWriteArrayList 集合。
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//CopyOnWriteArrayList 适用于多线程并发操作,集合中存储的对象是已订阅者划分的
//每个相同的eventType对应一个CopyOnWriteArrayList 集合
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
//subscriptions 不为null代表有相同订阅事件类型的 Subscription 对象。
//如果在相同订阅事件类型前提下,订阅对象和订阅方法完全一样,就抛异常。Subscription对象中有具体的 equals()判断方法
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
//根据注释中的 priority 值大小对相同订阅事件类型的 newSubscription 进行排序,
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;
}
}
//typesBySubscriber 每个订阅对象对应一个集合
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
Log.d("wangjian", "subscriber = "+subscriber.getClass().getName()+", eventType = "+eventType.getName()+", subscribedEvents = "+subscribedEvents.size());
//判断方法注释中sticky值是否为true,默认为false
if (subscriberMethod.sticky) {
//只有在注册之前调用了postSticky()方法,下面的post才会有效
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>).
//如果class A extends B,A 事件为粘性事件,参数为 A 和 B订阅方法都能能收到 A 对象的消息。
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 {
//eventInheritance = false情况,参数为 B 的注释方法是收不到消息的。
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
** SubscriberMethodFinder#findSubscriberMethods **
private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//先从METHOD_CACHE缓存中取出列表,没有的话就通过对象参数找出对应的订阅方法列表。
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
//通过默认的方式实例化EventBus,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#unregister 反注销方法 **
public synchronized void unregister(Object subscriber)
{
//通过subscriber 拿到 subscribedTypes 列表
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
//遍历解除绑定
unsubscribeByEventType(subscriber, eventType);
}
// 从 typesBySubscriber 表中移除掉
typesBySubscriber.remove(subscriber);
} else {
Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
//解除 key:eventType Value:subscriber 的Map表里面的元素
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}
** EventBus#post 发送事件方法 **
//post方法
public void post(Object event)
{
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
//是否是主线程
postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
//是否正在发送标志
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
while (!eventQueue.isEmpty()) {
//如果事件队列不为空,进行事件发送,
postSingleEvent(eventQueue.remove(0), postingState);
}
}
finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
//postSingleEvent 方法
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
//是否支持事件继承关系
if (eventInheritance) {
//查找所有订阅事件及其超类的超接口
List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
for (int h = 0; h < countTypes; h++) {
Class<?> clazz = eventTypes.get(h);
//将这些查找到的class与subscriptionsByEventType集合中的key进行匹配,并发送
subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
}
} else {
//发送事件
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
}
if (!subscriptionFound) {
if (logNoSubscriberMessages) {
Log.d(TAG, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
//postSingleEventForEventType
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass)
{
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//从subscriptionsByEventType集合中查找是否存在这个事件
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
//遍历发送
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
//发送给订阅者
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
}
finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
}
return false;
}
//postToSubscription 主要是线程选择后通过反射调用和异步执行在对应的线程
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread)
{
//通过 threadMode 确定应该在哪条线程中发送消息
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
//如果当前线程是主线程,直接反射调用注册方法 如果不是放到主线程去异步执行
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
** 看看主线程的切换执行 HandlerPoster **
//Looper为主线程 最大消息处理时间是10ms
HandlerPoster mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
//HandlerPoster 是继承 Handler 主线程消息处理
class HandlerPoster extends Handler
// 主线程任务执行队列
private final PendingPostQueue queue;
//加入主线程 执行
void enqueue(Subscription subscription, Object event)
{
//将subscription 和 消息事件对象封装到 PendingPost 中。
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
//加入队列
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
//发送消息通知
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
}
}
}
//消息的处理
@Override
public void handleMessage(Message msg)
{
boolean rescheduled = false;
try {
long started = SystemClock.uptimeMillis();
//死循环 循环去除队列数据
while (true) {
//从队列中取出 PendingPost 通过eventBus 对象直接发送。
//每次取出一个 header,会将下一个待发送 PendingPost 赋值给 header,直到发送完
//从执行队列里面去除一个post对象
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
handlerActive = false;
return;
}
}
}
//在主线程里面进行反射调用对应的方法
eventBus.invokeSubscriber(pendingPost);
//在规定时间内没发送完,退出本次任务,重新执行handleMessage()接着发送
long timeInMethod = SystemClock.uptimeMillis() - started;
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
//退出
return;
}
}
}
finally {
handlerActive = rescheduled;
}
}