Problems encountered in the use of EventBus

Posted by treppers on Mon, 08 Jul 2019 01:37:09 +0200

Speaking of EventBus, I think everyone is familiar with it. You haven't heard of it. Well, you still need to study it carefully. This blog is not to analyze the source code of EventBus, nor to talk about any philosophy of life, but to teach you how to use such a magic weapon. Who will ask you if EventBus will use it in the future? You can show off your car proudly and lead him to the car.

1. Preliminary understanding

Okay, first of all, let's take a look at the advantages of this picture. Does it save a lot of things? I feel like I have to copy and paste a paragraph, put it below. Every time I copy and paste, I feel a deep sense of guilt.  

EventBus is for Android Optimized Publish/Subscribe Event Bus. The main function is to replace Intent,Handler,BroadCast in Fragment, Activity, Service, threads to deliver messages. The advantages are less overhead, more elegant code. And decoupling the sender and the receiver.  
By the way, I know you won't see the address of the source code. This is the open source library address of EventBus on GitHub. https://github.com/greenrobot/EventBus

2. Introduction to beginners

Okay, here's how to use it.
(1) EventBus configuration
The EventBus framework is also designed in Builder mode, and some configuration information can be set through EventBusBuilder, such as throwing exceptions in debug mode.

EventBus     eventBus=EventBus.builder().throwSubscriberException(BuildConfig.DEBUG.build();
  • 1
  • 2
  • 1
  • 2

(2) Adding references

compile 'org.greenrobot:eventbus:3.0.0'
  • 1
  • 1

(3) Define an event type

public class MyEvent {
    private String msg;//You can also write something else about the content of the message you want to send.
    public MyEvent(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(4) Subscription/Unsubscription

EventBus.getDefault().register(this);//Subscribe

EventBus.getDefault().unregister(this);//Unsubscribe
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

Someone asked me where I put this thing. Okay, I'll tell you where I put it. First, write an encapsulation class.

public class EventUtil {
//Registration Events
    public static void register(Object context) {
        if (!EventBus.getDefault().isRegistered(context)) {
            EventBus.getDefault().register(context);
        }
    }
    //Relieve
    public static void unregister(Object context) {
        if (EventBus.getDefault().isRegistered(context)) {
            EventBus.getDefault().unregister(context);
        }
    }
    //send message
    public static void post(Object object) {
        EventBus.getDefault().post(object);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Then if the message is received in Activity, it is called in onCreate and onDestroy, and if it is fragment, well, it is still in these two methods... But it becomes

 EventUtil.register(this);//Subscription events
 EventUtil.register(this);//Cancel event
  • 1
  • 2
  • 1
  • 2

(5) Publishing events

EventBus.getDefault().post(new DataSynEvent());
  • 1
  • 1

(6) Subscription event handling

    @Subscribe(threadMode = ThreadMode.MAIN) //Execute in ui thread
    public void onDataSynEvent(DataSynEvent event) {

    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

ThreadMode has four total:

NAIN UI main thread
BACKGROUND background thread
POSTING is on the same thread as the publisher.
ASYNC asynchronous thread

What's their use? In fact, it tells you that only in the main thread can you update the UI. There's no time-consuming operation in the main thread. If necessary, use it with handler.

(7) Priority of Subscription Events

When it comes to priority, it's almost the same as the priority of the Boardcast receiver. The larger the number, the higher the priority. Usually, it's 0-100.

 @Subscribe(threadMode = ThreadMode.MAIN,priority = 100) //Execute priority 100 in ui thread
    public void onDataSynEvent(DataSynEvent event) {

    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

With priority, it's time for someone to ask if they can intercept the message and not let it go down. Of course, that's OK.

  EventBus.getDefault().cancelEventDelivery(event) ;//High-priority subscribers can terminate event delivery downward
  • 1
  • 1

(8) EventBus viscous event

When we learn broadcasting, we have a kind of broadcasting called sticky broadcasting. If you use regular broadcast send to send a message and then execute it in your onReceive for more than 10 seconds, the broadcast state will become cancelable, and sticky broadcast is to get rid of the 10 seconds limit. But for the sake of safety, I forgot which version of SDK had abandoned it.

So back to our problem, when you send a message and receive a registration message, you can't determine the order. For example, you request network data and subscription events to be executed simultaneously. If the data returns very fast, then you can't accept EventUtil.register(this) before the code has been executed. Here's the news.

This concept is understood like a subscription function in a qq email, if you subscribe to a public email.
Then they will push you messages, but you won't receive the messages they pushed before you subscribed.

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //Execute in ui thread
    public void onDataSynEvent(DataSynEvent event) {

    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

In version 2.4, there was a way to send sticky events. Later, it was found that there was still a way to send sticky events in version 3.0, so this was the way to send sticky events.

EventBus.getDefault().postSticky(new TestEvent());
  • 1
  • 1

We know that this sticky event exists in static variables, that is, if you don't kill him, he's always calling this in onDestory.

EventBus.getDefault().removeStickyEvent(new TestEvent());//Remove one

EventBus.getDefault().removeAllStickyEvents();//remove all
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

(9) Use of EventBus processor

I looked at the use of this thing for a while, and, alas, I didn't understand it very well. I visited the blog of Hongyang Great God and barely understood a little about this compile-time annotation of this thing...  
To get a deeper understanding, click here.
http://blog.csdn.net/Tencent_Bugly/article/details/51354693 [Tencent Bugly Dry Goods] Old Driver Teaches You "Speed Up" EventBus3
Just teach you how to do it.

Configuration in project build.gradle

buildscript {
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

Configuration in build.gradle of app

apply plugin: 'com.neenbedankt.android-apt'
apt {
    arguments {
        eventBusIndex "com.whoislcj.eventbus.MyEventBusIndex"
    }
}
dependencies {
    compile 'org.greenrobot:eventbus:3.0.0'
    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

At this time, compile once and automatically generate index classes. Under build generate source apt PakageName see the index class generated by annotation analysis, so that we can apply the index we generated when initializing EventBus.

Add an index to the default EventBus singleton

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();//If you do a singleton, put it in the singleton, and if not, put this sentence in the Application.
  • 1
  • 2
  • 1
  • 2

This is mainly to improve the speed of this code.

EventBus.getDefault().register(this);
  • 1
  • 1

(10) Code obfuscation

I found that many people were entangled with this problem, and finally they could not find any mistakes, so they could not be confused directly. Ha ha ha.
First come all.

-keepattributes *Annotation*//keep reflex
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;//This involves what your needs are. If you use EventBus processor for acceleration, you have to add this, as long as the classes and methods with this annotation are not confused, which facilitates decompilation... If you don't use acceleration, you don't need it.
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor//If you use ASYNC asynchronous threads
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Okay, that's all about the use of Eventbus. If you want to know more about the source code, here's the delivery door.

http://skykai521.github.io/2016/02/20/EventBus-3-0%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/ EventBus 3.0 Source Code Analysis
There are also these websites.
http://www.cnblogs.com/whoislcj/p/5595714.html Detailed usage of EventBus 3.0 for Android messaging (3)

Topics: Android github Gradle Fragment