EventBus Chinese Documentation, Android Development Interview Skills

Events can be published in any part of the code.All Subscriber s registered and matching this type receive this event:

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

Deepen understanding

Continue reading, or click This link To learn more about EventBus.

Configure EventBus

The EventBusBuilder class is used to configure various aspects of EventBus.For example, here's how to build an EventBus to stay calm when the published event does not have a Subscriber:

EventBus eventBus = EventBus.builder()
    .logNoSubscriberMessages(false)
    .sendNoSubscriberEvent(false)
    .build();

Another example is a crash when Subscriber throws an exception:

EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();

By default, EventBus catches exceptions thrown from Subscriber's callback method and issues a SubscriberExceptionEvent.This event can or cannot be handled.

For more detailed use see: Documentation for EventBusBuilder

Configure the default EventBus instance

Using EventBus.getdefault() makes it easy to get the same EventBus instance from anywhere in the application.EventBusBuilder also allows you to configure this default instance using the installDefaultEventBus() method.

For example, you can configure the default EventBus instance to re-throw exceptions that occur in the Subscriber method, and only for debug builds, because re-throwing exceptions can cause the application to crash abnormally:

EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();

It can only be used before the default EventBus instance is first used, which can only be called once.A subsequent call to installDefaultEventBus raises an exception.This ensures consistent application behavior.The Application class is a good place to configure the default EventBus instance.

Delivery Threads (ThreadMode)

EventBus helps you deal with threading issues: events can be published to a different thread than the publishing thread.A common use case is to handle UI changes.For Android, UI changes must occur in the UI (main) thread.On the other hand, network requests or any other time-consuming tasks cannot be run on the main thread.EventBus can help you address these issues and coordinate with your UI threads (you don't have to go deep into thread conversions, such as using AsyncTask).In EventBus, you can use one of four threading modes to specify the thread that invokes the event handling method.

ThreadMode.POSTING (default)

The Subscriber method is called on the same thread that published the event.This is the default behavior.Event delivery is done synchronously, and all Subscriber methods are called once the event is sent.Since thread switching is completely eliminated, this ThreadMode means minimal overhead.This is the recommended mode for simple tasks that take only a short time to complete and do not require the main thread.Event callbacks using this mode should return quickly to prevent blocking the thread sending the event (probably the main thread).

// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
    log(event.message);
}

ThreadMode.MAIN

Subscriber is called on the main thread of Android (and sometimes the UI thread).If the thread sending the event is the main thread, the Subscriber method is called directly (synchronous, as shown by ThreadMode.POSTING).Event callbacks using this mode must return quickly to prevent blocking the thread sending the event.

// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
    textField.setText(event.message);
}

ThreadMode.MAIN_ORDERED

Subscriber is called on the main thread of Android.Events are always queued for delivery to Subscriber, so calls to the event that originated are immediately returned.This ensures a more stringent and consistent sequence of event handling (hence called MAIN_ORDERED).For example, in ThreadMode.MAIN mode, when another event is published while processing an event, the second event is processed before the first event (in this case, a synchronous call, analogous to a method call).For MAIN_ORDERED, the first event is processed first, and the second event is processed at a later point in time, once the main thread has the processing power.

Event callbacks using this mode must return quickly to prevent blocking the thread sending the event.

// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onMessage(MessageEvent event) {
    textField.setText(event.message);
}

ThreadMode.BACKGROUND

Event callbacks will be called in the background thread.If the thread that published the event is not the main thread, the event callback will be invoked directly on the publishing thread.Otherwise, EventBus uses a background thread (singleton) to call each callback sequentially.Event callbacks using this mode should try to return quickly to try not to block background threads.

// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
    saveToDisk(event.message);
}

##ThreadMode: ASYNC

Event callback methods are always called on a separate thread.These threads will not be the threads that publish events, nor the main thread.The callback method post event to this mode will never wait.This mode should be used if the callback method performs time-consuming operations such as network requests.Avoid triggering a large number of long-running asynchronous tasks at the same time to limit the number of concurrent threads, EventBus uses thread pools to effectively reuse completed asynchronous task threads.

// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
    backend.send(event.message);
}

Sticky Events

For some events, we still care about the information it carries after it is post ed.For example, indicate that some initialization has been completed.Or, for sensor data or location information, you want to save the last value.You can use Sticky Events instead of implementing a cache yourself.EventBus keeps the last sticky event of a particular type in memory, which can be passed to Subscriber or queried directly.Therefore, no special code is needed to consider data that already exists.

Sticky event example

For example, we post ed a sticky event before:

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

Now a new Activity is started.All subscription sticky time methods receive sticky events from previous post s immediately upon registration:

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}
// UI updates must run on MainThread
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}
@Override
public void onStop() {
    EventBus.getDefault().unregister(this);    
    super.onStop();
}

Manual Get/Remove Sticky Events

As you can see, recent sticky events are automatically sent to matching Subscriber methods when they are registered
.Sometimes, however, it may be easier to manually check for sticky events and to remove (deplete) sticky events so that they are no longer transmitted.For example:

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
}

The removeStickyEvent method is overloaded: passing in a class returns the corresponding sticky event previously held.As a result, we can improve the previous examples:

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

Cancellation of Priorities and Events

Most use of EventBus does not use priority or cancel events, but it may be used in some special cases. For example, when an app is in the foreground, it triggers some code that updates the UI, otherwise it does something else.

Priority of Subscriber

You can provide a priority when registering Subscriber to change the order in which events are delivered:

@Subscribe(priority = 1);
public void onEvent(MessageEvent event) {
    ...
}

In the same ThreadMode, higher priority Subscribers receive events earlier than lower priority Subscribers. The default priority is 0.

Priority only affects Subscriber s in the same ThreadMode.

Cancel event delivery

Event delivery can be canceled by calling cancelEventDelivery(Object event) on the Subscriber's event processing thread. Further event delivery will be cancelled and no subsequent Subscriber will receive events.

// Called in the same thread (default)
@Subscribe
public void onEvent(MessageEvent event){
    // Process the event
    ...
    // Prevent delivery to other subscribers
    EventBus.getDefault().cancelEventDelivery(event) ;
}

Events are usually cancelled by high-priority Subscriber.Event cancellation is limited to event handling in ThreadMode.PostThread mode.

Subscriber Index

Subscriber index is a new feature of EventBus 3.This is an optional optimization to speed up the first subscriber registration process.

Subscriber indexes can be created by the EventBus annotation processor at compile time.Although indexing is not required, it is recommended for Android for optimal performance.

Prerequisites for Indexing

It is important to note that the @Subscriber method can only be indexed if the subscriber and event classes are both public.Similarly, due to the limitations of Java annotation processing itself, @Subscriber methods in internal classes are not recognized.

When an EventBus cannot use an index, it automatically falls back to the implementation of Runtime Reflection.This will still not prevent EventBus from working, but will be slightly slower.

How to generate an index

Using annotation Processor

If the Gradle plug-in version is less than 2.2.0, use android-apt to configure it.

Use the annotation Processor property to add an EventBus annotation processor in the currently built configuration file.The eventBusIndex parameter is also used to specify the fully qualified name of the generated index class.Add a code snippet similar to the following in the gradle build script:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ]
            }
        }
    }
}
dependencies {
    compile 'org.greenrobot:eventbus:3.1.1'
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}

Using kapt

If you use EventBus in Kotlin code, you need to replace annotation Processor with kapt:

apply plugin: 'kotlin-kapt' // ensure kapt plugin is applied
dependencies {
    compile 'org.greenrobot:eventbus:3.1.1'
    kapt 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}
kapt {
    arguments {
        arg('eventBusIndex', 'com.example.myapp.MyEventBusIndex')
    }
}

Using android-apt

If none of the above is helpful, you can use ( android-apt (A Gradle plug-in). Add the following code blocks to the Gradle build script:

buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
    compile 'org.greenrobot:eventbus:3.1.1'
    apt 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}
apt {
    arguments {
        eventBusIndex "com.example.myapp.MyEventBusIndex"
    }
}

How to Use Indexes

After the project is successfully compiled, the class specified by eventBusIndex is generated. This class is then used to initialize EventBus:

EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();

Or add a global index like this:

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
// Now the default instance uses the given index. Use it like this:
EventBus eventBus = EventBus.getDefault();

Is_Library_Indexing

Indexing is also for library code. In this case, there may be multiple index classes that can be added together when configuring EventBus:

EventBus eventBus = EventBus.builder()
    .addIndex(new MyEventBusAppIndex())
    .addIndex(new MyEventBusLibIndex()).build();
### Last

I have organized a complete learning thought and Android Develop Knowledge Complete PDF,Students who need it can get it by themselves.

![](https://img-blog.csdnimg.cn/img_convert/1ce6ddca75a18ecaf1836032eaad2040.png)

**[CodeChina Open Source Project: Android Summary of Learning Notes+Mobile Architecture Video+True subject for factory interview+Project Actual Source](https://codechina.csdn.net/m0_60958482/android_p7)** 

Of course, practice tells the truth, even if there is a learning line, we should also pay attention to practice. The content that we have learned can only be truly mastered if it is combined with practice. 

tBusAppIndex())
    .addIndex(new MyEventBusLibIndex()).build();
### Last

I have organized a complete learning thought and Android Develop Knowledge Complete PDF,Students who need it can get it by themselves.

[Outer Chain Picture Transfer in Progress...(img-OUH0mX8p-1630514495981)]

**[CodeChina Open Source Project: Android Summary of Learning Notes+Mobile Architecture Video+True subject for factory interview+Project Actual Source](https://codechina.csdn.net/m0_60958482/android_p7)** 

Of course, practice tells the truth, even if there is a learning line, we should also pay attention to practice. The content that we have learned can only be truly mastered if it is combined with practice. 

Tags: Android Design Pattern

Posted on Thu, 02 Sep 2021 01:44:28 -0400 by rstrik