觀察者模式在EventBus中的應用

git地址:https://github.com/greenrobot/EventBus.gitgit

EventBus是Android的事件發佈以及訂閱框架,經過解耦發佈者和訂閱者簡化Android事件傳遞,即消息傳遞。事件傳遞能夠用於四大組件間通信以及異步線程和主線程間通信等。

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;
    }
相關文章
相關標籤/搜索