EventBus getDefault()入口
除了注解,其他都和EventBus这个类有关系了
我们先从getDefault()方法开始分析
入口分析
这里的getDefault()静态方法,很容易看出,是一个
线程加锁的懒汉单例
具体通过new EventBus() 来创建实例
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
具体EventBus()构造
我们可以发现,具体的构造,其实是
初始化一些Map值,引用类,EventBusBuilder中的实现传递给EventBus类
其他的类,慢慢分析
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;
}
这里EventBusBuilder,只是一个 饿汉单例
在类创建之前,就已经创建出来了
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
而构造的赋值,只是把 Builder中的值传递到本类中
对应的EventBusBuilder对象
我们观察下面对应的EventBusBuilder类
有1个默认的线程池,管理线程
有很多boolean类型的变量,存储默认boolean属性
有2个List,分别存储Class类型 和
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; EventBusBuilder() { } /** Default: true */ public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) { this.logSubscriberExceptions = logSubscriberExceptions; return this; } /** Default: true */ public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) { this.logNoSubscriberMessages = logNoSubscriberMessages; return this; } /** Default: true */ public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) { this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent; return this; } /** Default: true */ public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) { this.sendNoSubscriberEvent = sendNoSubscriberEvent; return this; } /** * Fails if an subscriber throws an exception (default: false). * * Tip: Use this with BuildConfig.DEBUG to let the app crash in DEBUG mode (only). This way, you won't miss * exceptions during development. */ public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) { this.throwSubscriberException = throwSubscriberException; return this; } /** * By default, EventBus considers the event class hierarchy (subscribers to super classes will be notified). * Switching this feature off will improve posting of events. For simple event classes extending Object directly, * we measured a speed up of 20% for event posting. For more complex event hierarchies, the speed up should be * >20%. *
* However, keep in mind that event posting usually consumes just a small proportion of CPU time inside an app, * unless it is posting at high rates, e.g. hundreds/thousands of events per second. */ public EventBusBuilder eventInheritance(boolean eventInheritance) { this.eventInheritance = eventInheritance; return this; } /** * Provide a custom thread pool to EventBus used for async and background event delivery. This is an advanced * setting to that can break things: ensure the given ExecutorService won't get stuck to avoid undefined behavior. */ public EventBusBuilder executorService(ExecutorService executorService) { this.executorService = executorService; return this; } /** * Method name verification is done for methods starting with onEvent to avoid typos; using this method you can * exclude subscriber classes from this check. Also disables checks for method modifiers (public, not static nor * abstract). */ public EventBusBuilder skipMethodVerificationFor(Class clazz) { if (skipMethodVerificationForClasses == null) { skipMethodVerificationForClasses = new ArrayList<>(); } skipMethodVerificationForClasses.add(clazz); return this; } /** Forces the use of reflection even if there's a generated index (default: false). */ public EventBusBuilder ignoreGeneratedIndex(boolean ignoreGeneratedIndex) { this.ignoreGeneratedIndex = ignoreGeneratedIndex; return this; } /** Enables strict method verification (default: false). */ public EventBusBuilder strictMethodVerification(boolean strictMethodVerification) { this.strictMethodVerification = strictMethodVerification; return this; } /** Adds an index generated by EventBus' annotation preprocessor. */ public EventBusBuilder addIndex(SubscriberInfoIndex index) { if(subscriberInfoIndexes == null) { subscriberInfoIndexes = new ArrayList<>(); } subscriberInfoIndexes.add(index); return this; } /** * Installs the default EventBus returned by {@link EventBus#getDefault()} using this builders' values. Must be * done only once before the first usage of the default EventBus. * * @throws EventBusException if there's already a default EventBus instance in place */ 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."); } EventBus.defaultInstance = build(); return EventBus.defaultInstance; } } /** Builds an EventBus based on the current configuration. */ public EventBus build() { return new EventBus(this); } }
这里,看上去代码很多
大多数都是设置boolean值的方法
一个设置 线程池 ExecutorService的方法
一个 给List 添加 Class 的 skipMethodVerificationFor方法
一个给List添加SubscriberInfoIndex类型对象的 addIndex 方法
另外有 初始化外面EventBus对象的 installDefaultEventBus() 和 build() 方法
总体,就是设置boolean值,添加List对象的一个类
register(Object subscriber) 和 unregister(Object subscriber)
在外部使用的时候,我们最直接的,除了getDefault()这个单例以外
就是 register 和 unregister了
register
public void register(Object subscriber) {
Class subscriberClass = subscriber.getClass();
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
代码内容,也很好理解
- 通过传入的类(Activity中,一般写的是this,也就是Activity本身)
- 得到对应的 Class 对象, 再通过 SubscriberMethodFinder对象(下一篇一起分析这个类)去得到 一个 SubscriberMethod的List
- 把对应的List放入到一个容器中(应该用于之后通知的过程中,判断是否响应)
unregister
/** Unregisters the given subscriber from all event classes. */
public synchronized void unregister(Object subscriber) {
List> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class eventType : subscribedTypes) {
unsubscribeByEventType(subscriber, eventType);
}
typesBySubscriber.remove(subscriber);
} else {
Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
这里也比较好理解,通过容器,拿到对应的Class 的List
也就是某个Activity或者Fragment中,对应的注解类型
循环去遍历,最后在容器Map
post方法
我们知道,对应的值,是通过post去完成的
这里 用 ThreadLocal的线程包装类,去完成对应的线程记录和操作
对应的泛型PostingThreadState对象,记录对应的信息,将对应的线程放入一个List中
通过对应的状态,判断Looper.getMainLooper() == Looper.myLooper() 是否是主线程等操作, 将状态存入PostingThreadState的属性中
最后,遍历容器中的Event,
最后通过存储的Subscription中的subscriberMethod的method,反射去invoke调用方法。
下一篇我们可以了解Eventbus3代码分析(六):SubscriberMethodFinder类