EventBus concise tutorial

Posted by ADLE on Sat, 05 Mar 2022 13:47:00 +0100

brief introduction

EventBus is an event publish / subscribe framework for Android and Java programming. When using EventBus for event delivery, the publication and subscription of events are fully decomposed and coupled, which frees programmers from the traditional and original event delivery methods (such as Handler, BroadcastReceiver, Interface callback, etc.), focuses on the processing of business logic, and helps to develop more beautiful programs.

Basic concepts

  • Event: also known as message, an event is an object that contains the information to be transmitted by the event. A type of event belongs to one class, and different types of event objects belong to different classes. There are two types of events:

    • General events. When using general events, the subscription of events should be before the publication of events.
    • Sticky events: if you want an unsubscribed event to be received when you subscribe to it after publishing, use sticky events.
  • Publisher: usually refers to the class that publishes certain events.

  • Subscriber: usually refers to the class that subscribes to certain events. When a publisher publishes an event, EventBus will execute the subscriber method that has subscribed to the event, which is also called event processing method. Subscribers must register themselves from EventBus before they can receive events. In addition to registration, there is unregister. After de registering, subscribers will no longer receive events. In Android, if the subscriber is an Activity or Fragment, registration and de registration are usually carried out according to the life cycle.

Basic Usage

Introduce the use in Android.

  1. Add dependency.

    implementation 'org.greenrobot:eventbus:3.2.0'
    
  2. Define events. The event is a POJO (plain old Java object, simple java object) without specific requirements.

    public class MessageEvent {
     
        public final String message;
     
        public MessageEvent(String message) {
            this.message = message;
        }
    }
    
  3. Specify the subscriber. The subscriber needs to implement the event handling method (using the @ Subscribe annotation) so that it can be called when the event is published. Since EventBus 3.0, the name of event handling method can be specified arbitrarily.

    // This method will be called when a MessageEvent is posted (in the UI thread for Toast)
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
    }
    
    

    In addition, subscribers need to register and de register themselves from EventBus. Subscribers may not receive events until they register themselves.

    // Register and de register according to the life cycle
    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
     
    @Override
    public void onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop();
    }
    
  4. Publish events. Publishers can publish events anywhere in the code. After the event is published, all registered subscribers matching the current type of event can receive the event.

    EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
    

Advanced Usage

Thread mode

EventBus provides 5 different thread modes to invoke the subscriber method in the same or different thread as the event publishing thread.

  1. POSTING

    The subscriber will be called in the same thread that publishes the event, which is the default thread mode of EventBus. The subscriber is called immediately after the event is published, and the thread does not switch. This pattern requires the subscriber method to return quickly to avoid blocking the publishing thread.

    // The threadMode item cannot be specified
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessage(MessageEvent event) {
        log(event.message);
    }
    
  2. MAIN

    Subscribers will be called in the main thread (UI thread) of Android. If the publishing thread is the main thread, the usage here is the same as the POSTING mode. Here, event processing will block event generation, that is, once the event is published, the publisher code will not run down until the subscriber method is executed. This pattern requires the subscriber method to return quickly to avoid blocking the main thread. If the publishing thread is not the main thread, events are queued.

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessage(MessageEvent event) {
        textField.setText(event.message);
    }
    
  3. MAIN_ORDERED

    Subscribers will be called in the main thread (UI thread) of Android. Events are always queued so that they can be delivered to subscribers later, so the call to publish the event will return immediately, and the subscriber's method execution will be after the call to publish the event. This pattern enables a more rigorous and consistent sequence of event processing.

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    public void onMessage(MessageEvent event) {
        textField.setText(event.message);
    }
    
  4. BACK_GROUND

    The subscriber will be called in the background thread (sub thread). If the published thread is not the main thread, the subscriber method will be called directly in the publishing thread. If the publishing thread is the main thread, EventBus will use a single background thread to pass all its events in sequence. This mode requires the subscriber method to return quickly to avoid blocking the background thread.

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessage(MessageEvent event){
        saveToDisk(event.message);
    }
    
  5. ASYNC

    The subscriber method is called in a separate thread, which is outside the main thread and the publishing thread. The publishing thread will never block because it does not wait for the return of subscriber methods using this mode. Use this pattern if the execution of the subscriber method takes some time.

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessage(MessageEvent event){
        backend.send(event.message);
    }
    

Sticky events

Whether the event is sticky or not depends on the method used by the publisher when publishing the event:

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
  • post(): publish general events
  • postSticky(): Post sticky events.

After a sticky event is published, during subscriber registration, when its subscriber method uses the tag of sticky event, EventBus will send the last event of such event that has been reserved in memory to this subscriber method.

Allow manual acquisition and deletion of sticky events:

MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if(stickyEvent != null) {
    // "Consume" the sticky event
    EventBus.getDefault().removeStickyEvent(stickyEvent);
    // Now do something with it
}

Marking of sticky events:

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}

Topics: Android