Usage and explanation of EventBus event 3, eventbus 3

Source: Internet
Author: User
Tags eventbus

Usage and explanation of EventBus event 3, eventbus 3
Post event:

You can directly call 'eventbus. getDefault (). post (Event) to send events. The events can be sent to the corresponding Event subscriber Based on the Event type.

Publicvoid post (Object event) {PostingThreadState postingState = currentPostingThreadState. get (); List <Object> eventQueue = postingState. eventQueue; eventQueue. add (event); if (postingState. isPosting) {return;} else {postingState. isMainThread = logoff. getmainlogoff () = logoff. mylogoff (); postingState. isPosting = true; if (postingState. canceled) {thrownew EventBusException ("Internal error. abor T state was not reset ");} try {while (! EventQueue. isEmpty () {postSingleEvent (eventQueue. remove (0), postingState) ;}} finally {postingState. isPosting = false; postingState. isMainThread = false ;}} copy the code and you can see that the post object uses 'postingthreadstate' and is 'threadlocal'. Let's see the definition of 'postingthreadstate: copy the code finalstaticclass PostingThreadState {List <Object> eventQueue = new ArrayList <Object> (); boolean isPosting; boolean isMainThread; Subscribe subscribe; Object event; boolean canceled ;}


There is a member 'eventqueue '. Because it is ThreadLocal, the result is that each thread has a 'postingthreadstate' object, which contains an event queue, in addition, the 'isposting' Member indicates whether an event is being distributed. When an event is sent, events in the queue are retrieved and sent out in sequence. If an event is being distributed, then post directly adds the event to the queue and returns the event with a member 'ismainthread', which will be used in the actual event dispatching and will be used in 'postsingleevent.

privatevoid postSingleEvent(Object event, PostingThreadState postingState) throws Error {    Class<? extends Object> eventClass = event.getClass();    List<Class<?>> eventTypes = findEventTypes(eventClass); // 1boolean subscriptionFound = false;    int countTypes = eventTypes.size();    for (int h = 0; h < countTypes; h++) { // 2        Class<?> clazz = eventTypes.get(h);        CopyOnWriteArrayList<Subscription> subscriptions;        synchronized (this) {            subscriptions = subscriptionsByEventType.get(clazz);        }        if (subscriptions != null && !subscriptions.isEmpty()) { // 3for (Subscription subscription : subscriptions) {                postingState.event = event;                postingState.subscription = subscription;                boolean aborted = false;                try {                    postToSubscription(subscription, event, postingState.isMainThread); // 4                    aborted = postingState.canceled;                } finally {                    postingState.event = null;                    postingState.subscription = null;                    postingState.canceled = false;                }                if (aborted) {                    break;                }            }            subscriptionFound = true;        }    }    if (!subscriptionFound) {        Log.d(TAG, "No subscribers registered for event " + eventClass);        if (eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) {            post(new NoSubscriberEvent(this, event));        }    }}

Let's take a look at the 'postsingleevent' function. First, let's take a look at the first point. We call the 'findeventtypes 'function. The Code will not post it. The application of this function is, save the class object, implemented interface, and parent class object of this class to a List and return.

Next, go to step 2, traverse the List obtained in step 1, and perform step 3 operations on each class Object (that is, the event type) in the List, all subscribers of this event type are found to send events to them. As you can see, ** when we Post an event, the parent event of this event (the parent event of the event class) will also be Post, therefore, if an event subscriber receives an Object-type event, it can receive all events **.

We can also see that the event is actually sent through 'posttosubstatus' in Step 4, and the event and subscriber are saved to 'postingstate' before sending. Let's take a look at 'posttosubnotification'

privatevoid postToSubscription(Subscription subscription, Object event, boolean isMainThread) {    switch (subscription.subscriberMethod.threadMode) {    case PostThread:        invokeSubscriber(subscription, event);        break;    case MainThread:        if (isMainThread) {            invokeSubscriber(subscription, event);        } else {            mainThreadPoster.enqueue(subscription, event);        }        break;    case BackgroundThread:        if (isMainThread) {            backgroundPoster.enqueue(subscription, event);        } else {            invokeSubscriber(subscription, event);        }        break;    case Async:        asyncPoster.enqueue(subscription, event);        break;    default:        thrownew IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);    }}

'Threadmode' is used here:

  • If it is PostThread, directly execute
  • If it is MainThread, judge the current thread. If it is already the UI thread, it will be executed directly; otherwise, it will be added to the 'mainthreadposter' queue.
  • If it is a background thread, if it is currently a UI thread, add it to the 'backgroundposter' queue; otherwise, directly execute
  • For Async, add the 'asyncposter' queue.
BackgroundPoster
privatefinal PendingPostQueue queue;publicvoid enqueue(Subscription subscription, Object event) {    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);    synchronized (this) {        queue.enqueue(pendingPost);        if (!executorRunning) {            executorRunning = true;            EventBus.executorService.execute(this);        }    }}

The code is simple. In fact, the event to be sent is encapsulated into the 'pendingpost' object, and 'pendingpostqueue 'is a queue of the 'pendingpost' object, this event is put into the queue when 'enableput', and 'backgroundposter' is actually a Runnable object. If this Runnable object is not executed currently, add 'backgroundposter' to a thread pool in EventBus. When 'backgroundposter' is executed, events in the queue are retrieved and distributed in sequence. When there is no event for a long time, the thread to which 'backgroundposter' belongs will be destroyed, and a new thread will be created when the next Post event occurs.

HandlerPoster

'Mainthreadposter' is a 'handlerposter' object. 'handlerposter' inherits from 'handler'. The constructor receives a 'login' object. When an event is sent to 'handlerposter' enqueue, this event will be added to the queue like 'backgroundposter', but if the Message is not sent, the Message will be sent to itself.

void enqueue(Subscription subscription, Object event) {    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);    synchronized (this) {        queue.enqueue(pendingPost);        if (!handlerActive) {            handlerActive = true;            if (!sendMessage(obtainMessage())) {                thrownew EventBusException("Could not send handler message");            }        }    }}

In 'handlemessage', messages in the queue are retrieved in sequence and handed over to 'eventbus' to directly call the event processing function, the thread where the 'handlemessage' execution is located is the thread of the 'logging' passed in by the constructor. When 'eventbus' is constructed, the mainlogger' is passed in, so it will be executed in the UI thread.

AsyncPoster

'Asyncposter' is simple, and every event is added to the thread pool for processing.

publicvoid enqueue(Subscription subscription, Object event) {    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);    queue.enqueue(pendingPost);    EventBus.executorService.execute(this);}
Stick Event

You can use 'registersticky' to register the Stick event handler. As we know before, either 'register 'or 'registersticky' will call the 'subscribe' function, there is such a piece of code in 'subscribe:

 

That is, the event type is used to check whether the corresponding event exists from 'stickyevents'. If yes, the event is directly sent to the subscriber. When is this event stored? Like 'register 'and 'registersticky', there is also a 'poststicky' function with 'post:

if (sticky) {    Object stickyEvent;    synchronized (stickyEvents) {        stickyEvent = stickyEvents.get(eventType);    }    if (stickyEvent != null) {        // If the subscriber is trying to abort the event, it will fail (event is not tracked in posting state)        // --> Strange corner case, which we don't take care of here.        postToSubscription(newSubscription, stickyEvent, Looper.getMainLooper() == Looper.myLooper());    }}


When an event is sent through 'posticky', the last event of this type of event will be cached. When a subscriber registers through 'registersticky, the cached event is directly sent to it.

Next, the priority of the event and the corresponding resource


Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Related Article

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.