EventBus源码解析(一)
源码版本:
- EventBus:3.3.1
导航:
- 三方库-EventBus源码解析(一)
- 三方库-EventBus源码解析(二)
- 更多的文章看这里:主页
使用
定义事件
class MessageEvent(val message: String)
事件(Event
)是普通的对象,没有任何特定要求。
订阅方法
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: MessageEvent) {
Toast.makeText(applicationContext, event.message, Toast.LENGTH_SHORT).show()
}
创建一个接收事件的方法onMessageEvent
方法,使用注解@Subscribe
进行标注,同时标记事件接收的线程为主线程。
注册与注销
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
EventBus.getDefault().unregister(this)
super.onStop()
}
在订阅者内调用EventBus.getDefault().register(this)
方法进行注册,调用EventBus.getDefault().unregister(this)
方法进行反注册。
在Android
中,在Activity
和Fragment
中,您通常应该根据它们的生命周期进行注册。对于大多数情况,onStart/onStop
工作正常:
发送事件
普通事件
EventBus.getDefault().post(MessageEvent("Hello everyone!"))
粘性事件
EventBus.getDefault().postSticky(MessageEvent("Hello everyone!"))
源码
Subscribe注解
Subscribe类
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
// 线程模型,默认为POSTING(发布线程)。
ThreadMode threadMode() default ThreadMode.POSTING;
// 是否是粘性事件
boolean sticky() default false;
// 优先级
int priority() default 0;
}
Subscribe
为注解类,其只能声明在方法上,其有3个可配置选项。
-
threadMode
,线程模型,默认为POSTING
(发布线程)。 -
sticky
,是否是粘性事件,默认为false
。 -
priority
,优先级,默认为0。
ThreadMode类
public enum ThreadMode {
POSTING,
MAIN,
MAIN_ORDERED,
BACKGROUND,
ASYNC
}
ThreadMode
为枚举类,为线程模型
,一共有5种。
-
POSTING
,发布线程。 -
MAIN
,主线程。 -
MAIN_ORDERED
,主线程(有序)。 -
BACKGROUND
,后台线程。 -
POASYNCTING
,异步线程。
这里只是简单介绍,详细介绍看后面的-EventBus
的post
。
EventBus的创建
EventBus.getDefault()
EventBus --> getDefault方法
public class EventBus {
static volatile EventBus defaultInstance;
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
// 获取默认的EventBus对象,单例模式。
public static EventBus getDefault() {
EventBus instance = defaultInstance;
if (instance == null) {
synchronized (EventBus.class) {
instance = EventBus.defaultInstance;
if (instance == null) {
// 调用无参构造方法,创建EventBus。
instance = EventBus.defaultInstance = new EventBus();
}
}
}
return instance;
}
}
EventBus.getDefault()
方法,使用单例模式创建EventBus
对象,EventBus
的创建看new EventBus()
创建方式。
new EventBus()
EventBus --> 构造方法
public class EventBus {
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
public EventBus() {
// 调用EventBusBuilder为参的构造方法,传入一个默认的EventBusBuilder对象。
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
// 后面介绍,看EventBus的初始化。
...
}
}
new EventBus()
,使用的是默认EventBusBuilder
的配置,EventBusBuilder
的创建看EventBus.builder()
创建方式。
EventBus.builder()
EventBus --> builder方法
public static EventBusBuilder builder() {
return new EventBusBuilder();
}
EventBus.builder()
方法,创建EventBusBuilder
并返回,接下来我们看一下EventBusBuilder
类创建EventBus
的方法。
installDefaultEventBus
EventBusBuilder --> installDefaultEventBus方法
// 安装默认的EventBus
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.");
}
// 调用build方法创建EventBus,并给默认实例赋值。
EventBus.defaultInstance = build();
// 返回默认实例。
return EventBus.defaultInstance;
}
}
installDefaultEventBus()
方法,通过build
创建EventBus
对象,并赋值给EventBus.defaultInstance
,并返回其实例。
说明:
installDefaultEventBus()
方法,必须在第一次调用EventBus.getDefault()
之前调用,否则抛异常。installDefaultEventBus()
方法,只能调用一次,再次调用则抛异常。
build
EventBusBuilder --> build方法
// 基于当前配置构建一个EventBus。
public EventBus build() {
return new EventBus(this);
}
build()
方法,创建EventBus
对象,并传入当前EventBusBuilder
实例,我们先来看一下EventBusBuilder
类,然后再来看一下EventBus
的初始化。
小结
EventBus
可通过3种方式创建,EventBus.getDefault()
、new EventBus()
、EventBus.builder().build()
,它们最终都是通过EventBus(EventBusBuilder)
创建。
EventBusBuilder
EventBusBuilder
为构建者模式构建EventBus
,其提供了全部可配置的方法,以及一些其它获取的方法,我们来分别看一下。
配置项
EventBusBuilder类
public class EventBusBuilder {
// 默认线程池
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> skipMethodVerificationForClasses;
List subscriberInfoIndexes;
Logger logger;
MainThreadSupport mainThreadSupport;
EventBusBuilder() {
}
// 调用订阅方法异常时,是否打印异常信息,默认为true。
public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {
this.logSubscriberExceptions = logSubscriberExceptions;
return this;
}
// 没有订阅者时,是否打印异常信息,默认为true。
public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {
this.logNoSubscriberMessages = logNoSubscriberMessages;
return this;
}
// 调用订阅方法异常时,是否发送SubscriberExceptionEvent事件,默认为true。
public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {
this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent;
return this;
}
// 没有订阅者时,是否发送NoSubscriberEvent事件,默认为true。
public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {
this.sendNoSubscriberEvent = sendNoSubscriberEvent;
return this;
}
// 调用订阅方法异常时,是否抛出SubscriberException异常,默认为false。
public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {
this.throwSubscriberException = throwSubscriberException;
return this;
}
// 事件是否有继承性,默认为true。
public EventBusBuilder eventInheritance(boolean eventInheritance) {
this.eventInheritance = eventInheritance;
return this;
}
// 为EventBus提供一个自定义线程池,用于异步和后台事件传递。
public EventBusBuilder executorService(ExecutorService executorService) {
this.executorService = executorService;
return this;
}
// 跳过方法签名验证(目前未使用)
public EventBusBuilder skipMethodVerificationFor(Class> clazz) {
if (skipMethodVerificationForClasses == null) {
skipMethodVerificationForClasses = new ArrayList<>();
}
skipMethodVerificationForClasses.add(clazz);
return this;
}
// 是否忽略注解处理器生成的索引,默认为false。
public EventBusBuilder ignoreGeneratedIndex(boolean ignoreGeneratedIndex) {
this.ignoreGeneratedIndex = ignoreGeneratedIndex;
return this;
}
// 是否严格验证订阅方法,默认为false。
public EventBusBuilder strictMethodVerification(boolean strictMethodVerification) {
this.strictMethodVerification = strictMethodVerification;
return this;
}
// 添加注解处理器生成的索引
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
if (subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
// 设置日志处理者
public EventBusBuilder logger(Logger logger) {
this.logger = logger;
return this;
}
}
配置项的默认值,为属性的默认值。
1、异常处理配置
配置项 | 描述 | 默认值 |
---|---|---|
logSubscriberExceptions | 调用订阅方法异常时,是否打印异常信息 | true |
sendSubscriberExceptionEvent | 调用订阅方法异常时,是否发送SubscriberExceptionEvent 事件 |
true |
throwSubscriberException | 调用订阅方法异常时,是否抛出SubscriberException 异常 |
false |
logNoSubscriberMessages | 没有订阅者时,是否打印异常信息 | true |
sendSubscriberExceptionEvent | 没有订阅者时,是否发送NoSubscriberEvent 事件 |
true |
2、注解处理器配置
配置项 | 描述 | 默认值 |
---|---|---|
ignoreGeneratedIndex | 是否忽略注解处理器生成的索引 | false |
addIndex | 添加注解处理器生成的索引 | 无 |
3、其它配置
配置项 | 描述 | 默认值 |
---|---|---|
eventInheritance | 事件是否有继承性 | true |
executorService(ExecutorService) | 为EventBus 提供一个自定义线程池,用于异步和后台事件传递。 |
Executors.newCachedThreadPool() |
strictMethodVerification | 是否严格验证订阅方法 | false |
logger | 设置日志处理者 | 无 |
skipMethodVerificationFor(Class>) | 跳过方法验证(目前未使用) | 无 |
getLogger
EventBusBuilder --> getLogger方法
// 获取日志处理者
Logger getLogger() {
if (logger != null) {
return logger;
} else {
return Logger.Default.get();
}
}
getLogger()
方法,如果有调用logger()
方法设置过Logger
,则用设置过的Logger
,否则用默认的Logger.Default.get()
的Logger
,我们来看一下Logger
类。
Logger类
public interface Logger {
void log(Level level, String msg);
void log(Level level, String msg, Throwable th);
class JavaLogger implements Logger {
protected final java.util.logging.Logger logger;
public JavaLogger(String tag) {
logger = java.util.logging.Logger.getLogger(tag);
}
@Override
public void log(Level level, String msg) {
// TODO Replace logged method with caller method
logger.log(level, msg);
}
@Override
public void log(Level level, String msg, Throwable th) {
// TODO Replace logged method with caller method
logger.log(level, msg, th);
}
}
class SystemOutLogger implements Logger {
@Override
public void log(Level level, String msg) {
System.out.println("[" + level + "] " + msg);
}
@Override
public void log(Level level, String msg, Throwable th) {
System.out.println("[" + level + "] " + msg);
th.printStackTrace(System.out);
}
}
class Default {
public static Logger get() {
// 判断AndroidComponents是否可用,如果可用则用AndroidComponents的logger。
if (AndroidComponents.areAvailable()) {
return AndroidComponents.get().logger;
}
return new SystemOutLogger();
}
}
}
Logger
类,为日志处理者,是一个接口,它有两个log()
方法,JavaLogger
、SystemOutLogger
为其实现类。
Logger.Default.get()
方法,通过AndroidComponents.areAvailable()
方法,判断AndroidComponents
是否可用,如果可用则用AndroidComponents
实现类的logger
,否则用SystemOutLogger
,我们来看一下AndroidComponents
类。
AndroidComponents类
public abstract class AndroidComponents {
// AndroidComponents类实现者
private static final AndroidComponents implementation;
static {
// 实现者实例,如果Android SDK可用,则创建AndroidComponents实现者实例并赋值给它,否则赋值为null。
implementation = AndroidDependenciesDetector.isAndroidSDKAvailable()
? AndroidDependenciesDetector.instantiateAndroidComponents()
: null;
}
// AndroidComponents是否可用
public static boolean areAvailable() {
return implementation != null;
}
// 获取AndroidComponents实现类实例
public static AndroidComponents get() {
return implementation;
}
public final Logger logger;
public final MainThreadSupport defaultMainThreadSupport;
// 创建AndroidComponents,需要Logger、MainThreadSupport。
public AndroidComponents(Logger logger, MainThreadSupport defaultMainThreadSupport) {
this.logger = logger;
this.defaultMainThreadSupport = defaultMainThreadSupport;
}
}
AndroidComponents
类,为Android
组件,它持有Logger
、MainThreadSupport
,以及含有areAvailable()
、get()
两个静态方法。
implementation
属性为AndroidComponents
类实现类实例,通过AndroidDependenciesDetector
判断,如果Android SDK
可用,则创建AndroidComponents
实现类实例并赋值给它,否则赋值为null
,我们来看一下AndroidDependenciesDetector
类。
AndroidDependenciesDetector类
public class AndroidDependenciesDetector {
// 判断Android SDK是否是可用的,其内部判断为Looper.getMainLooper()是否有值。
public static boolean isAndroidSDKAvailable() {
try {
// 反射获取Looper类Class
Class> looperClass = Class.forName("android.os.Looper");
// 反射获取Looper类getMainLooper方法Method
Method getMainLooper = looperClass.getDeclaredMethod("getMainLooper");
// 反射获取Looper类getMainLooper方法返回值
Object mainLooper = getMainLooper.invoke(null);
// 判断Looper类getMainLooper方法返回值是否为空
return mainLooper != null;
}
catch (ClassNotFoundException ignored) {}
catch (NoSuchMethodException ignored) {}
catch (IllegalAccessException ignored) {}
catch (InvocationTargetException ignored) {}
return false;
}
private static final String ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME = "org.greenrobot.eventbus.android.AndroidComponentsImpl";
// 判断AndroidComponents是否是可用的,其内部判断为是否有AndroidComponentsImpl类。
public static boolean areAndroidComponentsAvailable() {
try {
Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME);
return true;
}
catch (ClassNotFoundException ex) {
return false;
}
}
// 创建AndroidComponents实现类,其内部为反射创建AndroidComponentsImpl类。
public static AndroidComponents instantiateAndroidComponents() {
try {
Class> impl = Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME);
return (AndroidComponents) impl.getConstructor().newInstance();
}
catch (Throwable ex) {
return null;
}
}
}
AndroidDependenciesDetector
类,它为Android
依赖发现者,它含有以下3个静态方法。
-
isAndroidSDKAvailable()
,判断Android SDK
是否是可用的,其内部判断为Looper.getMainLooper()
是否有值。 -
areAndroidComponentsAvailable()
,判断AndroidComponents
是否是可用的,其内部判断为是否有AndroidComponentsImpl
类。 -
instantiateAndroidComponents()
,创建AndroidComponents
实现类,其内部为反射创建AndroidComponentsImpl
类。
说明:
isAndroidSDKAvailable()
,通过它可以判断是否是在Android
平台。areAndroidComponentsAvailable()
,通过它可以判断是否是只引用了eventbus-java
库,未引用了eventbus
库(说明:eventbus-java
库为Java
库,eventbus
库为Android
库,引用eventbus
默认会引用eventbus-java
)。
我们再来看一下AndroidComponentsImpl
类。
AndroidComponentsImpl类
public class AndroidComponentsImpl extends AndroidComponents {
public AndroidComponentsImpl() {
super(new AndroidLogger("EventBus"), new DefaultAndroidMainThreadSupport());
}
}
AndroidComponentsImpl
类,它是AndroidComponents
的实现类,其Logger
为AndroidLogger
,其MainThreadSupport
为DefaultAndroidMainThreadSupport
。
AndroidLogger
类,其内部使用Log
进行打印,源码自行查看,我们接下来看一下DefaultAndroidMainThreadSupport
类。
DefaultAndroidMainThreadSupport类
public class DefaultAndroidMainThreadSupport implements MainThreadSupport {
@Override
public boolean isMainThread() {
return Looper.getMainLooper() == Looper.myLooper();
}
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, Looper.getMainLooper(), 10);
}
}
DefaultAndroidMainThreadSupport
类,为默认的Android
主线程支持类,其通过isMainThread()
判断是否是在主线程,通过createPoster()
创建主线程Poster
,为HandlerPoster
。
说明:
isMainThread()
方法,用Looper.myLooper() == Looper.getMainLooper()
比较的话,会浪费资源。因为Looper.myLooper()
方法获取Looper
,如果在新线程调用的话,ThreadLocal
会创建ThreadLocalMap
。建议改成用:Looper.getMainLooper().getThread() == Thread.currentThread()
。
getMainThreadSupport
EventBusBuilder --> getMainThreadSupport方法
// 获取MainThread支持
MainThreadSupport getMainThreadSupport() {
if (mainThreadSupport != null) {
// mainThreadSupport未使用
return mainThreadSupport;
} else if (AndroidComponents.areAvailable()) {
// AndroidComponents可用,则获取到其MainThreadSupport,即DefaultAndroidMainThreadSupport。
return AndroidComponents.get().defaultMainThreadSupport;
} else {
return null;
}
}
getMainThreadSupport()
方法,如果AndroidComponents
可用,则获取到其(即AndroidComponentsImpl
)MainThreadSupport
,即DefaultAndroidMainThreadSupport
。
小结
EventBusBuilder
为构建者模式构建EventBus
,其提供了全部可配置的方法。getLogger()
方法,如果是Android
平台,则为AndroidLogger
,否则为SystemOutLogger
。getMainThreadSupport()
方法,如果是Android
平台,则为DefaultAndroidMainThreadSupport
,否则为null
。
EventBusBuilder
相关的我们已经介绍完,接下来我们看一下EventBus
的初始化。
EventBus的初始化
EventBus
的所有方式创建,最终都会走到EventBus(EventBusBuilder)
构造方法,我们接下来看一下EventBus(EventBusBuilder)
构造方法。
EventBus --> 构造方法
private final Map, CopyOnWriteArrayList> subscriptionsByEventType;
private final Map
小结
EventBus
的初始化,创建了3个很重要的集合,subscriptionsByEventType
、typesBySubscriber
、stickyEvents
,详细解释看上面注释。- 创建了3个
Poster
,mainThreadPoster
(即HandlerPoster
)、backgroundPoster
、asyncPoster
,详细介绍看后面的-Poster
。- 获取
EventBusBuilder
的配置,并记录。- 创建
SubscriberMethodFinder
,用于查找订阅方法,详细介绍看后面的-SubscriberMethodFinder
。
EventBus的注册
EventBus --> register()
public void register(Object subscriber) {
if (AndroidDependenciesDetector.isAndroidSDKAvailable() && !AndroidDependenciesDetector.areAndroidComponentsAvailable()) {
// 是android平台但是没依赖eventbus(Android)库,则抛出异常。
throw new RuntimeException("It looks like you are using EventBus on Android, " +
"make sure to add the \"eventbus\" Android library to your dependencies.");
}
// 1、获取到订阅者的Class对象。
Class> subscriberClass = subscriber.getClass();
// 2、通过subscriberMethodFinder对象找到该订阅者的所有订阅方法。
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
// 3、同步,保证线程安全。
synchronized (this) {
// 4、遍历集合进行订阅
for (SubscriberMethod subscriberMethod : subscriberMethods) {
// 5、订阅,传入订阅者对象、该订阅者的订阅方法对象。
subscribe(subscriber, subscriberMethod);
}
}
}
register()
方法,为注册订阅者方法,通过subscriberMethodFinder
找到该订阅者的所有订阅方法,然后进行遍历依次订阅,SubscriberMethodFinder
相关我们单独介绍(看后面的-SubscriberMethodFinder
),我们先来看一下SubscriberMethod
类。
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;
public SubscriberMethod(Method method, Class> eventType, ThreadMode threadMode, int priority, boolean sticky) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
this.priority = priority;
this.sticky = sticky;
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
} else if (other instanceof SubscriberMethod) {
checkMethodString();
SubscriberMethod otherSubscriberMethod = (SubscriberMethod)other;
otherSubscriberMethod.checkMethodString();
// Don't use method.equals because of http://code.google.com/p/android/issues/detail?id=7811#c6
return methodString.equals(otherSubscriberMethod.methodString);
} else {
return false;
}
}
private synchronized void checkMethodString() {
if (methodString == null) {
// Method.toString has more overhead, just take relevant parts of the method
StringBuilder builder = new StringBuilder(64);
builder.append(method.getDeclaringClass().getName());
builder.append('#').append(method.getName());
builder.append('(').append(eventType.getName());
methodString = builder.toString();
}
}
@Override
public int hashCode() {
return method.hashCode();
}
}
SubscriberMethod
类,为订阅方法信息相关类,它记录了订阅方法上,Subscribe
注解的信息、参数信息、以及反射方法Method
(方便后续反射调用)。
在看subscribe()
方法前,我们先来看一下Subscription
类,其在subscribe()
方法(稍后介绍)内使用。
Subscription类
final class Subscription {
// 订阅者对象
final Object subscriber;
// 订阅方法
final SubscriberMethod subscriberMethod;
// 是否是活跃的
volatile boolean active;
Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
this.subscriber = subscriber;
this.subscriberMethod = subscriberMethod;
active = true;
}
@Override
public boolean equals(Object other) {
if (other instanceof Subscription) {
Subscription otherSubscription = (Subscription) other;
return subscriber == otherSubscription.subscriber
&& subscriberMethod.equals(otherSubscription.subscriberMethod);
} else {
return false;
}
}
@Override
public int hashCode() {
return subscriber.hashCode() + subscriberMethod.methodString.hashCode();
}
}
Subscription
类,为订阅者对象、订阅方法封装类,方便后续反射调用订阅者对象的订阅方法。
我们继续来看一下subscribe()
方法。
EventBus --> subscribe()
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
// 6、获取订阅方法的事件类型
Class> eventType = subscriberMethod.eventType;
// 7、封装Subscription对象(之后会将newSubscription添加到subscriptionsByEventType中)。
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
// 8、通过事件类型获取该事件的Subscription集合(之后会将newSubscription添加到subscriptions中)。
CopyOnWriteArrayList subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
// 9、集合为空,说明该事件为第一次订阅,则创建集合,并把当前Event类型存入subscriptionsByEventType中。
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
// 10、集合不为空,说明该事件已经被订阅过,则判断该订阅者是否有重复订阅的现象。
if (subscriptions.contains(newSubscription)) {
// 11、包含,则说明是重复订阅,此方法只有被register()方法调用,所以说明是重复注册,则抛出异常。
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
// 12、遍历该事件的所有订阅者,按照优先级进行插入。
int size = subscriptions.size();
// 13、i <= size,size最少为0,所以至少会执行一次for循环。
for (int i = 0; i <= size; i++) {
// 说明:
// 1. i == size,则说明是最后一个。
// 2. subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority,说明新的优先级高于当前的优先级。
// 14、如果是最后一个,或者新的优先级高于当前的优先级,则添加到当前位置,即当前位置后移,整体从高到低排序。
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
// 15、获取该订阅者订阅的事件的集合(之后会将eventType添加到subscribedEvents中)。
List> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
// 16、集合为空,则说明是第一次添加订阅者,则创建集合,并把当前订阅者存入typesBySubscriber中。
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
// 17、将事件加入到该订阅者订阅的事件的集合中
subscribedEvents.add(eventType);
// 18、判断该订阅方法是否是粘性事件,如果是粘性事件,则注册时就会通知事件,因为发送粘性事件不管之前注册还是之后注册都会通知。
if (subscriberMethod.sticky) {
// 19、是粘性事件,则进行通知订阅方法。
if (eventInheritance) { // eventInheritance:事件是否有继承性,默认为true。
// 20、事件有继承性,则通知所有已发送粘性事件符合是其自己或者其子类的事件。
// 21、获取所有已发送粘性事件,遍历判断是否符合是其自己或者其子类的事件。
Set, Object>> entries = stickyEvents.entrySet();
for (Map.Entry, Object> entry : entries) {
Class> candidateEventType = entry.getKey();
if (eventType.isAssignableFrom(candidateEventType)) {
// 22、符合是其自己或者其子类的事件,subscriptions则进行通知。
Object stickyEvent = entry.getValue();
// 23、调用checkPostStickyEventToSubscription方法进行检查发送。
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
// 24、事件没有继承性,则通知所有已发送粘性事件符合是其自己的事件。
Object stickyEvent = stickyEvents.get(eventType);
// 25、调用checkPostStickyEventToSubscription方法进行检查发送,stickyEvent有可能为null,因为可能之前没发送过此类事件的粘性事件。
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
subscribe()
方法,为订阅方法,其主要维护subscriptionsByEventType
、typesBySubscriber
数据,并处理粘性方法,如果是粘性方法则调用checkPostStickyEventToSubscription()
方法进行检查发送。
说明:
- 步骤6-14,为维护
subscriptionsByEventType
集合数据。步骤14,则会导致该事件的所有Subscription
,按订阅方法优先级从高到低排序。- 步骤15-17,为维护
typesBySubscriber
集合数据。- 步骤18-25,为判断是否是粘性方法,如果是则再判断事件是否有继承性,找到其对应的事件对象,最后调用
checkPostStickyEventToSubscription()
方法进行检查发送,如检测成功则会通知订阅方法的。eventInheritance
为事件是否有继承性,默认为true
,即会接收已经发送的粘性事件是其自己或者其子类的事件。- 如果已经发送了很多粘性事件,则遍历所有事件,所以会因有大量粘性事件而效率低下。
接下来,我们继续来看一下checkPostStickyEventToSubscription()
方法。
EventBus --> checkPostStickyEventToSubscription()
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
if (stickyEvent != null) {
// 26、如果粘性事件不为空,则进行发送粘性事件到订阅方法,并传入是否是在主线程发送。
postToSubscription(newSubscription, stickyEvent, isMainThread());
}
}
checkPostStickyEventToSubscription()
方法,为检查发送粘性事件到订阅方法的方法,如果粘性事件不为空,则进行发送,并传入是否是在主线程发送,后面postToSubscription()
就是我们的发送流程,详细介绍看后面的-EventBus
的post
。
EventBus --> isMainThread()
private boolean isMainThread() {
return mainThreadSupport == null || mainThreadSupport.isMainThread();
}
isMainThread()
方法,为检查当前线程是否是在主线程的方法。
说明:
- 如果不是
Android
平台则始终为true
,如果是Android
平台则通过mainThreadSupport.isMainThread()
判断是否是在主线程。
小结
EventBus
的注册,传入订阅者对象,通过反射获取到订阅者的Class
对象。- 通过
SubscriberMethodFinder
获取订阅者中所有订阅方法集合。- 遍历上面获取的集合,将订阅者和事件进行包装绑定为
Subscription
。- 维护
subscriptionsByEventType
、typesBySubscriber
集合数据,将Subscription
添加到subscriptionsByEventType
的当前eventType
(从订阅方法中获取)的List
中,将eventType
添加到typesBySubscriber
的当前订阅者的List
中。- 并判断此订阅方法是否是粘性方法,如果是粘性方法,并且之前已经发送过此粘性事件,则进行发送粘性事件到此订阅方法。
总结
以上就是EventBus
源码的第一部分,第二部分请看EventBus源码解析(二)。之后会出其它三方库
源码系列,请及时关注。如果你有什么问题,大家评论区见!
最后推荐一下我的网站,开发者的技术博客: devbolg.cn ,目前包含android相关的技术,之后会面向全部开发者,欢迎大家来体验!