[Eventbus Source parsing] Eventbus.register Method Details

Source: Internet
Author: User
Tags eventbus

Previously overview

In the previous article, we introduced the basic use of eventbus and some advanced techniques. This and several subsequent blogs will focus on parsing Eventbus.java to see how the author gracefully implements this seemingly simple event distribution/reception mechanism.

This article outlines

Profiling the register process, let's get started!

Method signature

The complete register method is signed as follows, and we usually call the register (this ) in fact the final call to the register (this, false, 0), in addition, using the Registersticky (This) makes the call, in fact, in the end is going to the same method.

Private synchronized void Boolean int Priority ) {    List<SubscriberMethod> subscribermethods = Subscribermethodfinder.findsubscribermethods ( Subscriber.getclass ());      for (Subscribermethod subscribermethod:subscribermethods) {        Subscribe (subscriber, Subscribermethod, sticky, priority);}    }

    • Declared as synchronized, because the subscribe method that is called is required to be executed in the synchronization block;
    • This register method actually does only one thing: Take out all the onevent methods of the target class (through reflection), subscribe to events (via subscribe)

Subscribe translation came to be "subscription, ordering", is the focus of the analysis of the content, the following to uncover her mysterious veil:

subscribe/Subscription

For people who are familiar with design patterns, the first to see Eventbus, the mind must be the Observer pattern/observer, this mode of implementation is nothing more than--the event's distributor has a list of subscribers, each time an event occurs, The distributor traverses and notifies subscribers in the list. Subscribers are free to join/exit their subscription list.

Register is a process of subscribing, so what you do in subscribe is "Add target method of target class to Subscriber list ". Let's combine the code to see.

Private voidSubscribe (Object subscriber, Subscribermethod Subscribermethod,BooleanStickyintPriority ) {Class<?> EventType =Subscribermethod.eventtype; Copyonwritearraylist<Subscription> subscriptions =Subscriptionsbyeventtype.get (EventType); Subscription newsubscription=NewSubscription (subscriber, Subscribermethod, priority); if(Subscriptions = =NULL) {Subscriptions=NewCopyonwritearraylist<subscription>();    Subscriptionsbyeventtype.put (EventType, subscriptions); } Else {        if(Subscriptions.contains (newsubscription)) {Throw NewEventbusexception ("subscriber" + subscriber.getclass () + "already registered to event" +EventType); }    }    //Starting with Eventbus 2.2 We enforced methods to is public (might change with annotations again)//subscriberMethod.method.setAccessible (true);    intSize =subscriptions.size ();  for(inti = 0; I <= size; i++) {        if(i = = Size | | newsubscription.priority >Subscriptions.get (i). Priority)            {Subscriptions.add (i, newsubscription);  Break; }} List<Class<?>> subscribedevents =Typesbysubscriber.get (subscriber); if(Subscribedevents = =NULL) {subscribedevents=NewArraylist<class<?>>();    Typesbysubscriber.put (subscriber, subscribedevents);    } subscribedevents.add (EventType); if(sticky) {if(eventinheritance) {//Existing Sticky events of all subclasses of EventType has to be considered. //note:iterating over all events 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<?&gt, 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); }    }}

Event is the key to the decoupling of the distributor/Subscriber, which communicates through the class of event. Therefore, we first take out the subscription list (Subscriptionsbyeventtype) of the target event, add the new rules, and throw exception if the register is duplicated. In the process of joining, the position that is inserted into the list is determined by the priority (the larger the int value, the higher the position, the greater the precedence). The next step is to add the correspondence between the Subscriber (that is, the target class) and the new EventType to Typesbysubscriber , which is used in subsequent lookups.

In the case of sticky , if the Eventbus supports event inheritance (eventinheritance = = True), all events for EventType and its ancestor classes are redistributed again, If not supported, only the target eventtype is distributed. (The event distributed at this time is from stickyevents)

unregister/logoff

This article finally analyzes the logoff process, the code is very simple.

 Public synchronized void Unregister (Object subscriber) {    List<Class<?>> subscribedtypes = typesbysubscriber.get (subscriber);     if NULL ) {        for ( class<?> eventtype:subscribedtypes) {            Unubscribebyeventtype ( Subscriber, EventType);        }        Typesbysubscriber.remove (subscriber);     Else {        "subscriber to unregister is not registered before:" + Subscriber.getclass ());}    }

Unregister, the binding relationship of the Eventtype-subscriber is first lifted (processed subscriptionsbyeventtype), and finally Subscriber-eventtypes unbind.

Next stage Notice

Anatomy of the Post process

[Eventbus Source parsing] Eventbus.register Method Details

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.