Detailed explanation of the use of EventBus3.0---refer to the official website

EventBus main roles:

·         Event object passed by Event 

·         Subscriber   to the Subscriber event  

The         publisher of the  Publisher   event

ThreadMode defines in which thread the         function executes 

1. Steps to use EventBus :

1. Define the event

public class MessageEvent{

    publicfinal String message;

    public MessageEvent(String message) {
       
        this.message = message;
        
    }

}

2. Prepare subscribers

The implementation of subscription is sent by calling the Subscriber method before sending the message EventBus3.0, but after 3.0 it is implemented by the @Subscribe annotation

// This method will be called when a MessageEvent is posted (in the UI thread for Toast)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEventevent) {

    Toast.makeText(getActivity(),event.message, Toast.LENGTH_SHORT).show();

}
 
// This method will be called when a SomeOtherEvent is posted
@Subscribe
public void handleSomethingElse(SomeOtherEventevent) {

    doSomethingWith(event);

}

It needs to be registered and deregistered according to the onStart/onStop method of the life cycle of Activities and Fragments. Subscribers also need to register and deregister on the bus. Only when the user registers, they can receive events.

@Override
public void onStart() {

    super.onStart();
    EventBus.getDefault().register(this);

}

@Override
public voidonStop() {

    EventBus.getDefault().unregister(this);
    super.onStop();

}

3. Send events

Events can be sent anywhere, and all matching event types can receive it

EventBus.getDefault().post(newMessageEvent("Hello everyone!"));

Two, EventBus four sending modes

ThreadMode: POSTING and the publisher are in the same thread

      By default, Subscribe and Post will be performed in the same Thread, and the delivery of Events is synchronous. Once the publication is completed, all Subscribers will be called. In this mode, you can Completely avoid thread (Thread) conversion, it occupies the least memory overhead, because it executes outside the main thread for a very short time, it is recommended to use this mode when completing some simple tasks. This mode may be executed in the main thread, and the event should be released quickly after the event is processed to avoid blocking the thread.

// Called in the same thread (default)
// ThreadMode is optional here
@Subscribe(threadMode = ThreadMode.POSTING)

public voidonMessage(MessageEventevent) {

    log(event.message);

}


ThreadMode: MAIN in theAndroidmain thread 

       Subscribers (Subscribers) will be called in the main thread of Android. If the sending (POST) is also in the main thread, the event processing will be executed immediately (similar to the description in ThreadMode.POSTING mode), and the same event processing is completed. should return immediately so as not to block the thread

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

    textField.setText(event.message);

}


ThreadMode: BACKGROUD background thread 

     The subscriber will be called in a background thread, and if the sending thread is the main thread, the processing of the event will be executed immediately. In the main thread, EventBus uses a single background thread and events will be delivered sequentially. The same event should be returned immediately after processing, so as not to block the thread

// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEventevent){

    saveToDisk(event.message);

}

ThreadMode: ASYNC asynchronous thread

       The handling of the event will be called in a separate thread. Independent of the sending thread and the main thread. With this mode, publishing events will not wait for their processing, and this mode can perform time-consuming operations such as: accessing the network. By limiting the number of threads, a large number of long-term asynchronous processing, to prevent multi-threaded concurrency.

EventBus reuses completed asynchronous processing using a thread pool to manage events.

// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public voidonMessage(MessageEventevent){

    backend.send(event.message);

}

3. EventBus configuration 

EventBus is managed using the EventBusBuilder class, e.g. keeping subscriptions and sending via the builder

EventBus eventBus = EventBus.builder()
    .logNoSubscriberMessages(false)
    .sendNoSubscriberEvent(false)
    .build();
 An example where a subscriber needs to throw an exception

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

Note: By default, subscribers can catch a SubscriberExceptionEvent without handling

The link below is the API of EventBusBuilder

http://greenrobot.org/files/eventbus/javadoc/3.0/org/greenrobot/eventbus/EventBusBuilder.html

Configure the default EventBus instance

Use EventBus.getDefault to easily get an instance of EventBus 

EventBusBuilder can also get the default instance by calling installDefaultEventBus

EventBus can be configured to throw exceptions, such as throwing exceptions under DEBUG

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

Note: The above operation can only be used before the default instance of EventBus is used for the first time, and then installDefaultEventBus () can be called to throw an exception. This design is to ensure the consistency of the APP.

 

四、Sticky Events

 Explanation: What is a Sticky event? Sticky means sticky. In Android development, the Sticky event only refers to a special type of event consumers who register the event after the event is published and can also receive the event. Such as StickyBroadcast, that is, sticky broadcast. Under normal circumstances, if the sender sends a broadcast, and the receiver registers its own receiver after the broadcast is sent, this means that the receiver cannot receive the broadcast just now, so Android introduces StickyBroadcast, which will be saved after the broadcast is sent. The broadcast (Intent) that has just been sent is sent to the amount, so that when the receiver registers the Receiver, it can receive the broadcast that has just been published. This allows us to pre-process some events and deliver these events to consumers when there are consumers.

       AndroidEventbus also provides such a function. The difference is that AndroidEvenBus will store all Sticky events. If an event does not need to be stored, it needs to be removed manually. Users publish events in the form of Sticky, and consumers also need to register in the form of Sticky. Of course, this registration is the same as the regular registration function except that it can receive Sticky events, and other types of events will also be processed normally.

Official description:

Some events carry information that is ofinterest after the event is posted. For example, an event signals that someinitialization is complete. Or if you have some sensor or location data and youwant to hold on the most recent values. Instead of implementing your owncaching, you can use sticky events. So EventBus keeps the last sticky event ofa certain type in memory. Then the sticky event can be delivered to subscribersor queried explicitly. Thus, you don’t need any special logic to consideralready available data.

Translation: Some events will bring messages after the event is published, for example, an event already exists when it is initialized. Or maybe you already have some sensor and location data, but want to get the latest values. Instead of implementing the cache yourself, you can use StickyEvent instead. So EventBus keeps the last sticky event of a specific type in memory. Sticky events can then be sent to subscribers, or queries can be displayed. Therefore, no needDo this by doing special logic to the data we already have.

Sticky Example

Let's say a sticky event was posted some time ago.

EventBus
    .getDefault()
    .postSticky(newMessageEvent("Hello everyone!"));
 
 

Now start an Activity. During this time so sticky users will immediately get the sticky events sent first

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

// UI updates must run on MainThread
@Subscribe(sticky=true,threadMode= ThreadMode.MAIN)
public voidonEvent(MessageEventevent){  
    textField.setText(event.message);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);    
    super.onStop();
}

Manually remove SickyEvent

As you can see, the last sticky event will automatically match the subscriber when the subscriber registers. But sometimes we need to manually check for sticky events. Sometimes in order to avoid re-delivery of sticky events we usually need to remove (consume) this event.

MessageEventstickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
// Better check that an event wasactually posted before
if(stickyEvent!=null) {

    // "Consume"the sticky event
    EventBus.getDefault().removeStickyEvent(stickyEvent);

    // Now dosomething with it

}

This removeStickyEvent is an overloaded method. When you use this class, the return value is the previous sticky event. Using this change we can change the previous example


Although we mostly use EventBus without priority and event cancellation, we still use it in some special cases. For example, when our app is in the foreground, it may trigger some UI logic, but when it is not visible, there will be different situations.
Cancellation of priorities and events

MessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);

// Better check that an event was actually posted before
if(stickyEvent!=null) {

    // Now do something with it

}

User priority

In order to change the delivery order of events, it is necessary to give events a priority to achieve the purpose.

Note: Priority does not affect the execution order of different thread modes (ie in ThreadMode). within the thread where the event is to be delivered (That is, in ThreadMode) high priority is executed before low priority. The default priority is 0.

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

 }

Cancel the delivery of an event

We can cancel user event processing through the function cancelEventDelivery(Object event). All subscribed events will be cancelled and subsequent subscriptions will not receive the event.

// Calledin the same thread (default)
@Subscribe
public void onEvent(MessageEventevent){

    // Process the event
    ...

    //Prevent delivery to other subscribers
    EventBus.getDefault().cancelEventDelivery(event) ;

}

Events are usually canceled by high-priority subscribers. Cancellation is limited to events that are running in the published thread (ThreadMode.PostThread).

Fives,

Subscriber Index

Subscriber index is a new feature of EventBus 3.0. This is an optional optimizer that can bring subscribers higher speeds.

The EventBus annotator creates the subscriber index at compile time. Although the EventBus does not have to use the index, it is recommended to use the Index for better performance.

Conditions of use of the index

Note: Indexes can only be used in @Subscriber methods, and when the class where the subscriber and Event are located is required to be public modified, and the @Subscriber annotation cannot be used in anonymous inner classes. When we do not use the EventBus index for event processing, it can also run normally, but because the reflection mechanism is used at runtime, the performance will be slightly lower.

How to generate indexes? Use of AnnotationProcessor

The Gradle plugin is required to be version 2.2.0 or later, and the annotationProcessor must be configured in build.gradle. You also need to use eventBusIndex to assign it to the class where you want to generate Index

android {
    defaultConfig{
        javaCompileOptions{
            annotationProcessorOptions{
               arguments = [ eventBusIndex:'com.example.myapp.MyEventBusIndex' ]

            }
        }
    }
}

dependencies {

    compile 'org.greenrobot:eventbus:3.0.0'
	annotationProcessor'org.greenrobot:eventbus-annotation-processor:3.0.1'

}

use kapt

 EnevtBus has also opened support for Kotlin. If you want to use Kotlin, you need to configure kapt in the annotationProcessor.

apply plugin: 'kotlin-kapt' // ensure kapt plugin is applied

dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    kapt'org.greenrobot:eventbus-annotation-processor:3.0.1'
}

capt {
    arguments {
        arg('eventBusIndex','com.example.myapp.MyEventBusIndex')
    }
}

In Android, the use of apt in Android-apt plugin should be configured in EventBusAnnotationProcessorAndroid

buildscript {

    dependencies{
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}


apply plugin: 'com.neenbedankt.android-apt'

dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}

apt {
    arguments {
        eventBusIndex"com.example.myapp.MyEventBusIndex"
    }
}

Use of indexes

After configuring the above operations, build the project, and then the business bean of EventBusIndex will be automatically generated. After generation, we can operate the index.

EventBus eventBus=EventBus.builder().addIndex(newMyEventBusIndex()).build();

You can also use the default instance of EventBus to operate

EventBus.builder().addIndex(newMyEventBusIndex()).installDefaultEventBus();

// Now the default instance uses the givenindex. Use it like this:

EventBus eventBus =EventBus.getDefault();

When we use it, there will be multiple scenes that need to use Index, and these scenes will be saved in our library. Use the following methods to meet our requirements

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

6. EventBus confusion

Since code obfuscation will change the method name and class name, EventBus cannot be used.

-keepattributes *Annotation*

-keepclassmembers class ** {

    @org.greenrobot.eventbus.Subscribe <methods>;

}

-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {

    <init>(java.lang.Throwable);

}

7. Asynchronous execution Note: Whether you use Index or not, you need to do the above operations during confusion

Asynchronous execution is like a thread pool with failure handling. AsyncExecutor wraps the exception into an event and publishes it automatically.

Disclaimer: AsyncExecutor will handle some exceptions in the background thread, but he is not the main class of EventBus.

We need AsyncExecutor when using it. Create() to create its instance and save it. Then implement the RunnableEx interface and pass it to the execution method of AsyncExecutor. When the Runnable is differentRunnableEx may throw an exception. If RunnableEx throws an exception, it will be encapsulated in ThrowableFailureEvent for publication.

An example is as follows:

AsyncExecutor.create().execute(

    new AsyncExecutor.RunnableEx() {

        @Override
        publicvoid run() throwsLoginException{

            // No need to catch any Exception (here:LoginException)
            remote.login();
            EventBus.getDefault().postSticky(new LoggedInEvent());

        }
    }
);

Receive part:

@Subscribe(threadMode=ThreadMode.MAIN)
public void handleLoginEvent(LoggedInEventevent) {

    // dosomething

}

@Subscribe(threadMode=ThreadMode.MAIN)
public void handleFailureEvent(ThrowableFailureEventevent) {

    // dosomething

}

八、AsyncExecutor Builder

Calling the static method AsyncExecutor.builder can customize the instance of AsyncExecutor

The original text is as follows:

If youwant to customize your AsyncExecutor instance, call the static method AsyncExecutor.builder(). It willreturn a builder which lets you customize the EventBusinstance, the thread pool, and the class of the failure event.

Anothercustomization option is the execution scope, which givesfailure events context information. Forexample, a failure event may be relevant only to a specific Activity instanceor class.

If yourcustom failure event class implements the HasExecutionScope interface,AsyncExecutor will set the execution scope automatically. Like this, yoursubscriber can query the failure event for its execution scope and reactdepending on it.

Postscript: This is the first time to write a blog! If the writing is not good, you can criticize people or not. Our slogan is to try not to do anything, and I hope you can give me more opinions . Finally, let me make up my mind that this is for my own learning, not for being famous .

The last official website of the plane ticket ha!!!

http://greenrobot.org/eventbus/documentation/how-to-get-started/


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325387719&siteId=291194637
Recommended