git地址:https://github.com/greenrobot/EventBus.gitgit
EventBus代碼簡潔易於使用,可用於應用內的消息事件傳遞,耦合低,方便快捷。github
基礎部分代碼爲:緩存
public class EventBusMain extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_main); EventBus.getDefault().register(this); } - 訂閱的事件 onEvent1 @Subscribe public void onEvent1(RemindBean bean){ } - 訂閱的事件 onEvent2 @Subscribe public void onEvent2(UserInfo bean){ } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } }
當須要發送消息傳遞的時候:app
EventBus.getDefault().post(new RemindBean())
即發佈者經過post()事件到EventBus,而後由EventBus將事件發送給各訂閱者。框架
以前的開發人員要想實現不一樣activity之間的數據傳遞,須要開發大量接口,而EventBus能夠方便快捷地解決這個問題。異步
發佈事件中的參數是Event的實例,而訂閱函數中的參數也是Event的實例,能夠推斷EventBus是經過post函數傳進去的類的實例來肯定調用哪一個訂閱函數的,是哪一個就調用哪一個,若是有多個訂閱函數,那麼這些函數都會被調用。ide
經過發佈不一樣的事件類的實例,EventBus根據類的實例分別調用了不一樣的訂閱函數來處理事件。函數
首先經過register()經過Subscriber肯定訂閱者以及經過Event肯定訂閱內容:oop
EventBus.getDefault().register(this); /** Convenience singleton for apps using a process-wide EventBus instance. */ public static EventBus getDefault() { if (defaultInstance == null) { synchronized (EventBus.class) { if (defaultInstance == null) { defaultInstance = new EventBus(); } } } return defaultInstance; } public void register(Object subscriber) { //訂閱者(subscriber)類的字節碼 Class<?> subscriberClass = subscriber.getClass(); //經過這個類的字節碼,拿到全部的訂閱的 event,存放在List中 List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { //循環遍歷全部的訂閱的方法,完成subscriber 和 subscriberMethod 的關聯 for (SubscriberMethod subscriberMethod : subscriberMethods) { subscribe(subscriber, subscriberMethod); } } }
在Subscribe中肯定消息的類型(是否爲粘滯消息)以及優先級,用於消息的發送。post
public @interface Subscribe { ThreadMode threadMode() default ThreadMode.POSTING; /** * If true, delivers the most recent sticky event (posted with * {@link EventBus#postSticky(Object)}) to this subscriber (if event available). */ boolean sticky() default false; /** Subscriber priority to influence the order of event delivery. * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of * delivery among subscribers with different {@link ThreadMode}s! */ int priority() default 0; }
// Must be called in synchronized block
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
- 1. 訂閱方法的eventType的字節碼
Class<?> eventType = subscriberMethod.eventType;
//訂閱者和訂閱方法封裝成一個Subscription 對象
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//subscriptionsByEventType 第一次也是null ,根據eventType
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
//第一次爲null
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
//key 爲 eventType, value 是subscriptions對象
subscriptionsByEventType.put(eventType, subscriptions);
} else {
//拋出異常
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
//獲取全部添加的subscriptions
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
// 會判斷每一個訂閱方法的優先級,添加到這個 subscriptions中,按照優先級
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
//獲取訂閱的方法集合
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
//爲空添加到 typesBySubscriber
typesBySubscriber.put(subscriber, subscribedEvents);
}
//訂閱事件添加到subscribedEvents集合中去
subscribedEvents.add(eventType);
//判斷是不是粘性事件的關聯
if (subscriberMethod.sticky) {
if (eventInheritance) {
// Existing sticky events of all subclasses of eventType have to be considered.
// Note: Iterating over all events may be inefficient with lots of sticky events,
// thus data structure should be changed to allow a more efficient lookup
// (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
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);
}
}
}
經過調用Android的handler監聽傳遞的事件,即發佈者發佈、訂閱者訂閱模式,這裏用到了觀察者模式。
protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) { super(looper); this.eventBus = eventBus;
//調用Android的handler監聽 this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage; queue = new PendingPostQueue(); } public void enqueue(Subscription subscription, Object event) { PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event); synchronized (this) { queue.enqueue(pendingPost); if (!handlerActive) { handlerActive = true; if (!sendMessage(obtainMessage())) { throw new EventBusException("Could not send handler message"); } } } } @Override public void handleMessage(Message msg) { boolean rescheduled = false;
//拋出異常 try { long started = SystemClock.uptimeMillis(); while (true) { PendingPost pendingPost = queue.poll(); if (pendingPost == null) { synchronized (this) { // Check again, this time in synchronized pendingPost = queue.poll(); if (pendingPost == null) { handlerActive = false; return; } } } eventBus.invokeSubscriber(pendingPost); long timeInMethod = SystemClock.uptimeMillis() - started; if (timeInMethod >= maxMillisInsideHandleMessage) { if (!sendMessage(obtainMessage())) { throw new EventBusException("Could not send handler message"); } rescheduled = true; return; } } } finally { handlerActive = rescheduled; } }
經過findSubscriberMethod()根據subscriberClass找到訂閱的method:
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) { //先從緩存中取 List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass); //第一次 null if (subscriberMethods != null) { return subscriberMethods; }
if (ignoreGeneratedIndex) { subscriberMethods = findUsingReflection(subscriberClass); }
else { subscriberMethods = findUsingInfo(subscriberClass); }
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass + " and its super classes have no public methods with the @Subscribe annotation"); }
else { //找到以後添加到緩存中,key是 subscriber ;value 是:methods
METHOD_CACHE.put(subscriberClass, subscriberMethods); return subscriberMethods; } }
獲取消息狀態,肯定傳給正確的訂閱者:
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) { FindState findState = prepareFindState(); 將訂閱者的subscriberClass 存儲起來,保存在一個FindState 類中的subscriberClass 同時賦值給clazz變量中 // void initForSubscriber(Class<?> subscriberClass) { // this.subscriberClass = clazz = subscriberClass; //} findState.initForSubscriber(subscriberClass); while (findState.clazz != null) {進入循環中 //獲取subscriberInfo 信息,返回null findState.subscriberInfo = getSubscriberInfo(findState); if (findState.subscriberInfo != null) { SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods(); for (SubscriberMethod subscriberMethod : array) { if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) { findState.subscriberMethods.add(subscriberMethod); } } } else { //全部信息保存到findState中 findUsingReflectionInSingleClass(findState); } //查找父類中的方法 findState.moveToSuperclass(); } return getMethodsAndRelease(findState); } private List<SubscriberMethod> getMethodsAndRelease(FindState findState) { //取出裏面的subscriberMethods List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods); findState.recycle(); synchronized (FIND_STATE_POOL) { for (int i = 0; i < POOL_SIZE; i++) { if (FIND_STATE_POOL[i] == null) { FIND_STATE_POOL[i] = findState; break; } } } //返回集合 return subscriberMethods; }