Android 8.1的SystemUI的recents模塊實現(xiàn)了Eventbus室谚,用于recents模塊內(nèi)通信毡鉴。本文分析其代碼實現(xiàn)原理崔泵。
EventBus概述
?? Eventbus是由greenrobot組織貢獻的一個Android事件發(fā)布/訂閱輕量級框架,基于觀察者設(shè)計模式,通過解耦發(fā)布者和訂閱者簡化Android事件傳遞猪瞬。Android SystemUI源碼中的EventBus只簡單的實現(xiàn)了事件傳遞憎瘸,沒有實現(xiàn)線程模型,粘性事件等陈瘦,可以看作是簡化版的Eventbus幌甘。
Eventbus實現(xiàn)
??在SystemUI中按照如下圖所示發(fā)布者/訂閱者模式實現(xiàn)EventBus。
??EventBus的處理流程是訂閱者在EventBus中register(訂閱)事件痊项,當(dāng)發(fā)布者發(fā)送出事件時锅风,EventBus根據(jù)事件查找到訂閱了該事件的訂閱者列表,并逐一調(diào)用訂閱者的onBusEvent()事件響應(yīng)函數(shù)鞍泉,把事件傳給訂閱者處理皱埠。
1.事件訂閱
??register訂閱事件最終調(diào)用到如下所示函數(shù)(這里貼出的是主要的代碼)。傳入的參數(shù)為subscriber的類對象咖驮,獲取該類所有函數(shù)边器,遍歷并通過函數(shù)isValidEventBusHandlerMethod判斷是否為EventBus的事件響應(yīng)函數(shù)(public、final類型托修,void返回類型和函數(shù)名以onBusEvent開頭)忘巧,找到響應(yīng)函數(shù)后,保存到mEventTypeMap對象屬性中睦刃,mEventTypeMap是個HashMap對象實例砚嘴,以Event的子類對象的Class屬性為key,ArrayList<EventHandler>為值眯勾。如上面的類圖所示枣宫,EventHandler有類型為EventHandlerMethod的屬性method婆誓,而EventHandlerMethod中屬性mMethod類型為Method吃环,用于記錄訂閱者的事件響應(yīng)函數(shù)。
/**
* Registers a new subscriber.
*/
private void registerSubscriber(Object subscriber, int priority,
MutableBoolean hasInterprocessEventsChangedOut) {
... ...
Class<?> subscriberType = subscriber.getClass();
... ...
// Find all the valid event bus handler methods of the subscriber
MutableBoolean isInterprocessEvent = new MutableBoolean(false);
Method[] methods = subscriberType.getDeclaredMethods();
for (Method m : methods) {
Class<?>[] parameterTypes = m.getParameterTypes();
isInterprocessEvent.value = false;
if (isValidEventBusHandlerMethod(m, parameterTypes, isInterprocessEvent)) {
Class<? extends Event> eventType = (Class<? extends Event>) parameterTypes[0];
ArrayList<EventHandler> eventTypeHandlers = mEventTypeMap.get(eventType);
if (eventTypeHandlers == null) {
eventTypeHandlers = new ArrayList<>();
//記錄事件響應(yīng)函數(shù)
mEventTypeMap.put(eventType, eventTypeHandlers);
}
EventHandlerMethod method = new EventHandlerMethod(m, eventType);
EventHandler handler = new EventHandler(sub, method, priority);
eventTypeHandlers.add(handler);
subscriberMethods.add(method);
sortEventHandlersByPriority(eventTypeHandlers);
}
}
}
/**
* @return whether {@param method} is a valid (normal or interprocess) event bus handler method
*/
private boolean isValidEventBusHandlerMethod(Method method, Class<?>[] parameterTypes,
MutableBoolean isInterprocessEventOut) {
int modifiers = method.getModifiers();
if (Modifier.isPublic(modifiers) &&
Modifier.isFinal(modifiers) &&
method.getReturnType().equals(Void.TYPE) &&
parameterTypes.length == 1) {
... ...
//METHOD_PREFIX:"onBusEvent"
if (EventBus.Event.class.isAssignableFrom(parameterTypes[0]) &&
method.getName().startsWith(METHOD_PREFIX)) {
isInterprocessEventOut.value = false;
return true;
}
... ...
return false;
}
2.事件發(fā)送洋幻、響應(yīng)
??發(fā)送事件時調(diào)用EventBus類的send()郁轻、post()、sendOnMainThread()函數(shù)文留,三個都函數(shù)只有一個Event類型的參數(shù)好唯。接著會調(diào)用queueEvent() 函數(shù),通過mEventTypeMap.get(event.getClass())獲取相應(yīng)的EventHandler燥翅,然后通過其中的Method類型屬性對象反射調(diào)用事件響應(yīng)函數(shù)骑篙。至此事件傳遞完成。
private void processEvent(final EventHandler eventHandler, final Event event) {
... ...
try {
Object sub = eventHandler.subscriber.getReference();
if (sub != null) {
//反射調(diào)用事件響應(yīng)函數(shù)
eventHandler.method.invoke(sub, event);
} else {
Log.e(TAG, "Failed to deliver event to null subscriber");
}
} catch (IllegalAccessException e) {
Log.e(TAG, "Failed to invoke method", e.getCause());
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
}
}
總結(jié)
??Android SystemUI中的EventBus實現(xiàn)如上分析森书。與greenrobot組織使用注解來標(biāo)識事件響應(yīng)函數(shù)不同靶端,SystemUI通過函數(shù)名前綴的方式標(biāo)識事件響應(yīng)函數(shù)谎势。兩者都是通過反射調(diào)用事件響應(yīng)函數(shù)。有興趣深入了解的同學(xué)可以下載SystemUI源碼或者EventBus.java來進一步學(xué)習(xí)杨名。