看文章前提一句埋泵,重點(diǎn)看代碼里面注釋
一.EventBus是什么谨娜?
EventBus是一款針對(duì)Android優(yōu)化的發(fā)布/訂閱事件總線
二.How to Use?
//就這幾個(gè)方法,不再贅述攀例,默認(rèn)你用過(guò)
fun onCreate() {
EventBus.getDefault().register(this)
}
fun onDestory() {
EventBus.getDefault().unregister(this)
}
fun send() {
EventBus.getDefault().post(DemoEvent())
}
@Subscribe
public fun onReceiveDemoEvent(event: DemoEvent) {
//balabala
}
三.源碼解析(針對(duì)3.1.1版本)
1.EventBus.getDefault().register(Object) 注冊(cè)EventBus
public void register(Object subscriber) {
//注冊(cè)對(duì)象獲取class
Class<?> subscriberClass = subscriber.getClass();
//從訂閱查找器里查找方法
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
//遍歷把方法訂閱方法
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
subscriberMethodFinder 對(duì)象從哪里來(lái)羡亩?
先從構(gòu)建說(shuō)起,反手就是一個(gè)建造者模式
public class EventBusBuilder {
//EventBus的線程池状勤,無(wú)限大鞋怀,可復(fù)用
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
//布爾值全部為標(biāo)志位,跟你平時(shí)加flag執(zhí)行不同邏輯一樣持搜,不需要特地理解密似,看具體用法
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;
//這玩意兒沒(méi)用到,
List<Class<?>> skipMethodVerificationForClasses;
//通過(guò)APT注解,在編譯時(shí)就生成對(duì)應(yīng)解析注解為優(yōu)化方式葫盼,這個(gè)默認(rèn)為空残腌,即你找不到
List<SubscriberInfoIndex> subscriberInfoIndexes;
//寫(xiě)日志的玩意兒
Logger logger
//內(nèi)部就2個(gè)方法,判斷是否為主線程贫导,創(chuàng)建handler(作者給這些handler起名叫poster發(fā)射器)
MainThreadSupport mainThreadSupport;
......
}
//獲取單例
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
//雖然 public 抛猫,別調(diào)用,沒(méi)啥用
public EventBus() {
this(DEFAULT_BUILDER);
}
//就是各種賦值孩灯,賦值闺金,
EventBus(EventBusBuilder builder) {
logger = builder.getLogger();
//一些事件集合哈,發(fā)送的事件就是往這里的峰档,說(shuō)到底還是往map里面存
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
//3種發(fā)射器败匹,區(qū)別后面講
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
//重點(diǎn)看看這個(gè)寨昙,把他拉出來(lái)
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
//后面這些就不講了,就是各種flag的賦值掀亩,然后把線程池給單例
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
SubscriberMethodFinder 字面意思舔哪,訂閱方法的查找器
SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,boolean ignoreGeneratedIndex)
參數(shù)作用
1.subscriberInfoIndexes 這個(gè)呢其實(shí)就是apt的插件生成的一些EventBusIndex,注入進(jìn)去
2.strictMethodVerification 默認(rèn)值false槽棍,如果為true捉蚤,會(huì)拋異常哈。具體點(diǎn)到這個(gè)類看看就可以
3.ignoreGeneratedIndex 忽略注解炼七,僅通過(guò)反射方式拿取外里,默認(rèn)false哈,就是會(huì)去找index那種
下面看看這個(gè)類里面的方法,回到主題
一開(kāi)始講的這個(gè)EventBus.getDefault().register(XXX)方法里面
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods =
//看這里這里
subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
也就是這個(gè)方法 findSubscriberMethods
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
//有緩存直接取了哈特石。METHOD_CACHE又是一個(gè)hashMap
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
if (ignoreGeneratedIndex) {
//剛才說(shuō)過(guò)的,開(kāi)了ignoreGeneratedIndex就直接用反射了
subscriberMethods = findUsingReflection(subscriberClass);
} else {
//findUsingInfo 這個(gè)方法是真正根據(jù)要訂閱的類查找訂閱方法了
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
//這里提一嘴鳖链,平時(shí)你們寫(xiě)了register但是類里又沒(méi)有Subscribe注解姆蘸,你App就炸了,這里報(bào)的
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
//查完之后芙委,存?zhèn)€緩存逞敷,常規(guī)操作
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
找到findUsingInfo這個(gè)方法
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();//準(zhǔn)備一個(gè)查找的state
findState.initForSubscriber(subscriberClass);//根據(jù)當(dāng)前類初始化 鏈接1
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);//從subscriberInfoIndexes里面找方法,鏈接2
if (findState.subscriberInfo != null) {
//subscriberInfo 這個(gè)里面有方法名什么的灌侣,就是提前已經(jīng)根據(jù)注解解析完了
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
for (SubscriberMethod subscriberMethod : array) {
//檢查添加方法推捐,這里面會(huì)拋出異常,總之不要有同名方法侧啼。沒(méi)問(wèn)題就是add
if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
findState.subscriberMethods.add(subscriberMethod);
}
}
} else {
//沒(méi)找到只好用反射的方式了牛柒。。鏈接3
findUsingReflectionInSingleClass(findState);
}
findState.moveToSuperclass();
}
//最后把訂閱好的方法痊乾,返回去皮壁。然后回收f(shuō)indState。就是考慮復(fù)用哪审。蛾魄。
return getMethodsAndRelease(findState);
}
//相關(guān)方法哈.看title找下把
//鏈接1
void initForSubscriber(Class<?> subscriberClass) {
this.subscriberClass = clazz = subscriberClass;
skipSuperClasses = false;
subscriberInfo = null;
}
//鏈接2
private SubscriberInfo getSubscriberInfo(FindState findState) {
if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
if (subscriberInfoIndexes != null) {
//這里看到了么。湿滓。眼熟的subscriberInfoIndexes 滴须,就是apt注解提前生成的類里,遍歷去找
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
//鏈接3 這就是個(gè)反射叽奥。先根據(jù)類扔水,獲取注解,然后解析朝氓。后面一樣的铭污。恋日。也是查找下是不是有,然后添加添加嘹狞。
//2.X版本方式岂膳。。以前人們不是天天說(shuō)磅网,反射谈截,影響效率么,所以現(xiàn)在用原則上用上面那個(gè)效率高涧偷。
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// This is faster than getMethods, especially when subscribers are fat classes like Activities
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException("@Subscribe method " + methodName +
"must have exactly 1 parameter but has " + parameterTypes.length);
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException(methodName +
" is a illegal @Subscribe method: must be public, non-static, and non-abstract");
}
}
}
拿到訂閱的方法之后簸喂,要跟對(duì)象綁定起來(lái),在register的方法的遍歷里
subscribe(subscriber, subscriberMethod);
參數(shù)1就是你register的傳進(jìn)來(lái)的對(duì)象燎潮,參數(shù)2是這個(gè)對(duì)象類里面找到的方法
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//這里開(kāi)始喻鳄,是先去把方法放到subscriptionsByEventType 這個(gè)事件類型的緩存
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
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這個(gè)就是isRegister,unRegister使用的哈确封。
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
//以下就是stikyEvent相關(guān)除呵,checkPostStickyEventToSubscription,如果本地有粘性事件
//注冊(cè)粘性事件的時(shí)候一并取了
if (subscriberMethod.sticky) {
if (eventInheritance) {
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 {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
斷點(diǎn)看實(shí)際效果爪喘,可以看到通過(guò)subscriberMethodFinder 找到的SubscriberMethod有參數(shù)名颜曾,對(duì)應(yīng)方法,線程模式等等
SubscriberMethod.png
再看 subscriptionsByEventType 緩存的對(duì)象秉剑,就是把事件類型作為key泛豪,前面所拿到的Subscription作為value,進(jìn)行緩存
subscriptionsByEventType.png
最后看typesBySubscriber緩存的對(duì)象侦鹏,就是把object作為key诡曙,該object訂閱對(duì)應(yīng)的事件類型作為value
typesBySubscriber.png
2.EventBus.getDefault().unregister(Object) 解注冊(cè)EventBus
public synchronized void unregister(Object subscriber) {
//subscribedTypes register的時(shí)候往這個(gè)里面放過(guò),解注冊(cè)的時(shí)候移除
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
//這個(gè)遍歷的for循環(huán)里面略水,把對(duì)應(yīng)的事件全部移除了噢
unsubscribeByEventType(subscriber, eventType);
}
typesBySubscriber.remove(subscriber);
} else {
logger.log(Level.WARNING, "Subscriber ...: " + subscriber.getClass());
}
}
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--;
}
}
}
}
3.EventBus.getDefault().post(EventObject())發(fā)送事件
最后一步了岗仑,發(fā)送事件
public void post(Object event) {
//currentPostingThreadState 這個(gè)是ThreadLocal,可以看作數(shù)據(jù)結(jié)構(gòu)map聚请,key為線程荠雕,value為你設(shè)定的對(duì)象,每個(gè)線程不同驶赏。
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isMainThread = isMainThread();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
while (!eventQueue.isEmpty()) {
//遍歷發(fā)送事件
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
.........
//回調(diào)這個(gè)方法
subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
........
}
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//從訂閱的方法里炸卑,取出這個(gè)方法
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
//取出對(duì)應(yīng)的事件跟subscription
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
//發(fā)送到對(duì)應(yīng)地方去了
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;
}
POSTING,MAIN,MAIN_ORDERED,這些就是訂閱事件的線程模式
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
//默認(rèn)模式
case POSTING:
invokeSubscriber(subscription, event);
break;
//主線程
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
break;
//主線程異步
case MAIN_ORDERED:
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
//子線程
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
//不管在哪個(gè)線程,都異步
case ASYNC:
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
關(guān)于poster煤傍,其實(shí)就是一開(kāi)始創(chuàng)建的線程池中取出線程來(lái)運(yùn)行盖文,其中比較特殊的是mainThreadPoster,這個(gè)其實(shí)是handler蚯姆,把mainLooper取出來(lái)給他五续,創(chuàng)建出來(lái)的
Object getAndroidMainLooperOrNull() {
try {
return Looper.getMainLooper();
} catch (RuntimeException e) {
// Not really a functional Android (e.g. "Stub!" maven dependencies)
return null;
}
}
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;
...
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, looper, 10);//這里
}
}
//最初的構(gòu)造者模式中洒敏,對(duì)應(yīng)的地方。
EventBus(EventBusBuilder builder) {
......
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
.....
}
最后來(lái)看看invokeSubscriber(Subscription subscription, Object event)
void invokeSubscriber(Subscription subscription, Object event) {
try {
//其實(shí)就是調(diào)用method的invoke方法疙驾,其中subscription.subscriber是訂閱對(duì)象凶伙,event是對(duì)應(yīng)發(fā)送的事件
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (InvocationTargetException e) {
handleSubscriberException(subscription, event, e.getCause());
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
}
}