If you don’t know how to use EventBus3.0, you can use EventBus3.0.

The thread of control

There are four ways to control threads in EventBus:

POSTING means that the thread receiving the event method is the same as the thread sending the event method. If the POSTING event is in the main thread, the POSTING event is also in the main thread. If the sending event is in the child thread, then the receiving event will also be executed by the child thread that sent the event. It’s going to be consistent.

2.MAIN: MAIN thread mode, regardless of which thread sends the receive event, the receive event must be executed in the MAIN thread. This solves the problem of only updating the UI in the main thread.

3.BACKGROUND: BACKGROUND thread mode. If the sending event is sent in the main thread, the receiving event will be executed in a new child thread. The sending event is executed in the child thread, and the receiving event is executed in the child thread that sent the event. This mode is suitable for time-consuming tasks.

4.ASYNC: new thread mode. No matter in which thread the sending event is executed, a new child thread will be created to receive the receiving event.

Examples of thread control code:

The event receiving code prints the Name of the current thread in each thread mode. For coding convenience, all the code is completed in an Activity:

@Subscribe(threadMode = ThreadMode.MAIN)
public void onBusMain(String message){
    Log.v("bus","main"+Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.POSTING)
public void onBusPosting(String message){
    Log.v("bus","posting"+Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onBusBackground(String message){
    Log.v("bus","background"+Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.ASYNC)
public void onBusAsync(String message){
    Log.v("bus","async"+Thread.currentThread().getName());
}Copy the code

Add two buttons to the interface:




    

    Copy the code

Copy the code

Button click events, one in the main thread and one in the child thread:

public void mainThread(View view){
    EventBus.getDefault().post("bus");
}

public void sonThread(View view){
    new Thread(new Runnable() {
        @Override
        public void run() {
            EventBus.getDefault().post("bus");
        }
    }).start();
}Copy the code

Click the main thread button,logcat prints the result:

09-30 15:05:13. 296, 18777-18777 / com. Jelly. The eventbus V/bus: Mainmain 09-30 15:05:13.296 18777-18777/com.jelly. Eventbus V/bus: Postingmain 09-30 15:05:13.296 18777-26381/com.jelly. Eventbus V/bus: Backgroundpool-1-thread-2 09-30 15:05:13.296 18777-26380/com.jelly. Eventbus V/bus: Asyncpool 1-thread-1Copy the code

Click the child thread button and locat prints the result:

09-30 15:23:11. 628, 11282-11282 / com. Jelly. The eventbus V/bus: Mainmain 09-30 15:23:11.616 11282-11392/com.jelly. Eventbus V/bus: Postingthread-220 09-30 15:23:11.616 11282-11392/com.jelly. Eventbus V/bus: Backgroundthread-220 09-30 15:23:11.616 11282-11394/com.jelly. Eventbus V/bus: Asyncpool 1-thread-1Copy the code

The above four conclusions can be discussed from the printed results above.

priority

Subscribe(priority = 1) ¶ EventBus can set the priority of each receive event method to @SUBSCRIBE (priority = 1).

@Subscribe(threadMode = ThreadMode.MAIN,priority = 1)
public void onBus1(String msg){
    Log.v("bus",1 + msg);
}Copy the code

The higher the value of priority, the higher the receiving order. If you specify two methods with values of priority 1 and 2, then priority 2 is received first and priority 1 is received later, and the event delivery can be cut off within the method by cancelEventDelivery(). Example code:

package com.jelly.eventbus; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; /** * Created by Jelly on 2016/9/30. */ public class PriorityActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_priority); EventBus.getDefault().register(this); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } @Subscribe(threadMode = ThreadMode.MAIN,priority = 0) public void onBus(String msg){ Log.v("bus",0 + msg); } @Subscribe(threadMode = ThreadMode.MAIN,priority = 1) public void onBus1(String msg){ Log.v("bus",1 + msg); } @Subscribe(threadMode = ThreadMode.POSTING,priority = 2) public void onBus2(String msg){ Log.v("bus",2 + msg); } @Subscribe(threadMode = ThreadMode.MAIN,priority = 3) public void onBus3(String msg){ Log.v("bus",3 + msg); } public void click(View View){eventbus.getDefault ().post(" message "); }}Copy the code

Logcat result without cancel event:

10-04 15:58:25.505 4614-4614/com.jelly. Eventbus V/bus: 3 message 10-04 15:58:25. 2 message 10-04 15:58:25.505 4614-4614/com.jelly. Eventbus V/bus: 1 message 10-04 15:58:25.505 4614-4614/com.jelly. 0 newsCopy the code

Now add cancel event passing:

@Subscribe(threadMode = ThreadMode.POSTING,priority = 2)
public void onBus2(String msg){
    Log.v("bus",2 + msg);
    EventBus.getDefault().cancelEventDelivery(msg);
}Copy the code

Print result:

10-04 15:55:00.685 4614-4614/com.jelly. Eventbus V/bus: 3 message 10-04 15:55:00.685 4614-4614/com.jellyCopy the code

Handlers may only abort the incoming event, because they are POSTING and the event handlers may only abort the incoming event. As you can see from the cancelEventDelivery source code, the last judgment in the following code throws this exception if the current event receiving method is not POSTING:

public void cancelEventDelivery(Object event) { PostingThreadState postingState = currentPostingThreadState.get(); if (! postingState.isPosting) { throw new EventBusException( "This method may only be called from inside event handling methods on the posting thread"); } else if (event == null) { throw new EventBusException("Event may not be null"); } else if (postingState.event ! = event) { throw new EventBusException("Only the currently handled event may be aborted"); } else if (postingState.subscription.subscriberMethod.threadMode ! = ThreadMode.POSTING) { throw new EventBusException(" event handlers may only abort the incoming event"); } postingState.canceled = true; }Copy the code

Sticky event

EventBus supports sticky events. Sticky events are subscribed after the event is sent, not before the event is sent. The event receiving method can also be subscribed, which is specified by @subscribe (sticky = true). Sample code:

package com.jelly.eventbus; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; /** * Created by Jelly on 2016/10/4. */ public class StickyActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_sticky); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } @Subscribe(threadMode = ThreadMode.MAIN,sticky = true) public void onBus(String msg){ Log.v("bus",msg); } public void click(View View){eventBus.getDefault ().poststicky (" message "); EventBus.getDefault().register(this); }}Copy the code

Print result:

10-04 16:26:43.401 2405-2405/com.jelly. Eventbus V/bus: messageCopy the code

efficiency

Joined in the EventBus3.0 EventBusAnnotationProcessor speed: 1. In the project of gradle apt, introduced in dependencies, add the classpath ‘com. Neenbedankt. Gradle. Plugins: android – apt: 1.8’, the results are as follows:

Dependencies buildscript {repositories {jcenter ()} {the classpath 'com. Android. View the build: gradle: 2.2.0' classpath 'com. Neenbedankt. Gradle. Plugins: android - apt: 1.8' / / NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }Copy the code

2. Apply apt plugin in app Module build.gradle, set the package name and class name of index generated by APT, add the following code:

apply plugin: 'com.neenbedankt.android-apt' apt { arguments { eventBusIndex "com.jelly.eventbus.MyEventBusIndex" } } apt 'org. Greenrobot: eventbus -- the annotation processor: 3.0.1'Copy the code

The results are as follows:

apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' Android {compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig {applicationId "Com. Jelly. Eventbus" 19 targetSdkVersion 23 versionCode minSdkVersion 1 versionName testInstrumentationRunner "1.0" "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } apt { arguments { eventBusIndex "com.jelly.eventbus.MyEventBusIndex" } } dependencies { compile fileTree(dir: 'libs', include: [' *. Jar ']) androidTestCompile (' com. Android. Support. The test. The espresso: espresso - core: 2.2.2 ', {exclude group: 'com.android.support', module: 'support - annotations'}) compile' com. Android. Support: appcompat - v7:23.4.0 'testCompile junit: junit:' 4.12 'compile 'org. Greenrobot: eventbus: 3.0.0' apt 'org. Greenrobot: eventbus -- the annotation processor: 3.0.1'}Copy the code

MyEventBusIndex = MyEventBusIndex = MyEventBusIndex = MyApplication;

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();Copy the code

You can use it now, la la la la!