EventBus getDefault()入口
除了注解东抹,其他都和EventBus這個類有關系了
我們先從getDefault()方法開始分析
入口分析
這里的getDefault()靜態(tài)方法帕识,很容易看出潜腻,是一個
線程加鎖的懶漢單例
具體通過new EventBus() 來創(chuàng)建實例
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
具體EventBus()構造
我們可以發(fā)現(xiàn)窍育,具體的構造卡睦,其實是
初始化一些Map值,引用類蔫骂,EventBusBuilder中的實現(xiàn)傳遞給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,只是一個 餓漢單例
在類創(chuàng)建之前辽旋,就已經(jīng)創(chuàng)建出來了
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<Class<?>> skipMethodVerificationForClasses;
List<SubscriberInfoIndex> 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).
* <p/>
* 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%.
* <p/>
* 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);
}
}
這里,看上去代碼很多
大多數(shù)都是設置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<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
代碼內(nèi)容束铭,也很好理解
- 通過傳入的類(Activity中廓块,一般寫的是this,也就是Activity本身)
- 得到對應的 Class<?> 對象契沫, 再通過 SubscriberMethodFinder對象(下一篇一起分析這個類)去得到 一個 SubscriberMethod的List
- 把對應的List放入到一個容器中(應該用于之后通知的過程中带猴,判斷是否響應)
unregister
/** Unregisters the given subscriber from all event classes. */
public synchronized void unregister(Object subscriber) {
List<Class<?>> 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中拴清,對應的注解類型
循環(huán)去遍歷,最后在容器Map<Object, List<Class<?>>> typesBySubscriber 中
remove掉對應的key会通,也就是Activity或者Fragment中所有注解的方法
post方法
我們知道口予,對應的值,是通過post去完成的
這里 用 ThreadLocal的線程包裝類涕侈,去完成對應的線程記錄和操作
對應的泛型PostingThreadState對象沪停,記錄對應的信息,將對應的線程放入一個List中
通過對應的狀態(tài)驾凶,判斷Looper.getMainLooper() == Looper.myLooper() 是否是主線程等操作牙甫, 將狀態(tài)存入PostingThreadState的屬性中
最后掷酗,遍歷容器中的Event调违,
最后通過存儲的Subscription中的subscriberMethod的method,反射去invoke調用方法泻轰。