替代Intent、Handler、BroadCast在Fragment、Activity、Service、线程之间传递消息
观察者模式:对象间的一种一对多的依赖关系,即当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。有发布者和订阅者(又称观察者)
1.EventBus#getDefault():
双重校验并加锁的单例模式生成EventBus实例
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
register(thsi);
传入MainActivity实例
缓存中如果有对应class的订阅方法列表,返回
List<SubscriberMethod> subscriberMethods
subscriberMethods = findUsingInfo(subscriberClass);
findUsingReflectionInSingleClass
如果没有则通过反射的方式获取订阅者类中的所有声明方法,然后在这些方法里面寻找以@Subscribe作为注解的方法 添加到subscriberMethods中
subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode, subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
生成subscriberMethods成功的话会加入到缓存中
EventBus#subscribe()
返回subscriberMethods之后,register方法的最后会调用subscribe方法:
将所有含@Subscribe注解的订阅方法最终保存在subscriptionsByEventType中。
subscriptionsByEventType.put(eventType, subscriptions);
它是一个Map,key为eventType,value为CopyOnWriteArrayList<Subscription>
EventBus#post():
把传入的event,保存到了当前线程中的一个变量PostingThreadState的eventQueue中。
EventBus#postSingleEvent():
postSingleEventForEventType(event, postingState, eventClass);
根据Event类型从subscriptionsByEventType中取出对应的subscriptions,最后调用postToSubscription()方法。
EventBus#postToSubscription():
会根据threadMode来判断应该在哪个线程中去执行方法:
POSTING:执行invokeSubscriber()方法,就是直接反射调用;
MAIN:首先去判断当前是否在UI线程,如果是的话则直接反射调用,否则调用mainThreadPoster#enqueue(),即把当前的方法加入到队列之中,然后通过handler去发送一个消息,在handler的handleMessage中去执行方法。具体逻辑在HandlerPoster.java中;
BACKGROUND:判断当前是否在UI线程,如果不是的话直接反射调用,是的话通过backgroundPoster.enqueue()将方法加入到后台的一个队列,最后通过线程池去执行;
事件的发送和接收,主要是通过subscriptionsByEventType列表,我们将订阅即接收事件的方法存储在这个列表,发布事件的时候在列表中查询出相对应的方法并执行。
网友评论