由于EventBus 3.0 和之前的版别差异较大,下面介绍的内容是基于EventBus3.0 。EventBus,是一个基于Publish/Subscribe的事情总线结构, 这儿不做过多具体介绍。

下面是EventBus工程和文档地址:

GitHub : github.com/greenrobot/…
官方文档:greenrobot.org/eventbus/do…

装备

这儿介绍一下装备。

  1. 根本装备:
    在app 工程下的build.gradle 中增加依靠:

    dependencies {
        ......  // 省掉部分依靠
        implementation 'org.greenrobot:eventbus:3.1.1'
    }
    
  2. 假如运用索引(index)在app 工程下的build.gradle 中增加依靠:

    android {
        defaultConfig {
            .... // 
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [ eventBusIndex : 'com.cfox.eventbusdemo.index.EventBusIndex' ]
                }
            }
        }
    }
    dependencies {
        implementation 'org.greenrobot:eventbus:3.1.1'
        annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
    }
    

快速运用

  1. 创立音讯类
    这个类能够任意定义, 作为传输运用

    public class MessageObjectOne {
        private String info;
        public String getInfo() {
            return info;
        }
        public void setInfo(String info) {
            this.info = info;
        }
    }
    
  2. 注册
    注册运用EventBus实例register(Object subscriber)办法进行注册。

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
    
  3. 刊出
    刊出运用EventBus实例unregister(Object subscriber)办法进行注册。

    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }
    
  4. 订阅接事情
    订阅接纳办法运用注解@Subscribe

    @Subscribe(threadMode = ThreadMode.MAIN, priority = 2, sticky = true)
    public void subMessageOne(MessageObjectOne msgOne) {
        Log.d(TAG, "subMessageOne: " + msgOne.getInfo());
    }
    

    上面代码发现,注解@Subscribe 有三个参数,还有不同的值。下面会介绍

  5. 发布音讯

    MessageObjectOne object = new MessageObjectOne();
    object.setInfo("hello world");
    EventBus.getDefault().post(object);
    

@Subscribe参数

threadMode

  • ThreadMode.POSTING(默认):假如运用事情处理函数指定了线程模型为POSTING,那么该事情在哪个线程发布出来的,事情处理函数就会在这个线程中运转,也便是说发布事情和接纳事情在同一个线程。在线程模型为POSTING的事情处理函数中尽量防止履行耗时操作,由于它会阻塞事情的传递,甚至有可能会引起ANR.

  • ThreadMode.MAIN:
    事情的处理会在UI线程中履行。事情处理时间不能太长,长了会ANR的。

  • ThreadMode.BACKGROUND:假如事情是在UI线程中发布出来的,那么该事情处理函数就会在新的线程中运转,假如事情原本便是子线程中发布出来的,那么该事情处理函数直接在发布事情的线程中履行。在此事情处理函数中禁止进行UI更新操作。

  • ThreadMode.ASYNC:无论事情在哪个线程发布,该事情处理函数都会在新建的子线程中履行,同样,此事情处理函数中禁止进行UI更新操作。

priority
订阅办法的优先级影响订阅办法的履行次序。优先级越高越被先履行。
sticky
假如设置为true则该订阅事情为粘性事情(后面会具体介绍)。

运用索引(index)

在EventBus中运用索引能够进步app功率。运用索引的装备上面已经介绍了,下面介绍一下:

arguments = [ eventBusIndex : 'com.cfox.eventbusdemo.index.EventBusIndex' ]

上面这句是装备生成索引的目录(com.cfox.eventbusdemo.index)和索引类的类名(EventBusIndex), 装备好索引后,重新build一下工程就会生成索引类。

索引为什么能进步app的功率,假如没有运用索引,在注册的时分会经过反射获取类中订阅的事情,运用索引后注册时在索引中查询订阅事情,所以功率会进步很多。

  • 增加运用索引
    装备好索引后,还要将生成的索引增加的项目中,不然索引是不会收效的。索引建议在运用的Application 中增加,如下:

    public class App extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            EventBus.builder().addIndex(new EventBusIndex()).installDefaultEventBus();
        }
    }
    

假如在项目中运用EventBus.getDefault()办法运用EventBus,在运用索引的时分一定要运用installDefaultEventBus()办法增加索引。

有的文章中运用build()办法增加索引,如下办法:

public class App extends Application {
    private EventBus mEventBus;
    @Override
    public void onCreate() {
        super.onCreate();
        mEventBus = EventBus.builder().addIndex(new EventBusIndex()).build();
    }
    public  EventBus getEventBus() {
        return mEventBus;
    }
}

注意:假如运用这种办法增加索引一定要运用build()回来的EventBus实例, 假如运用EventBus.getDefault()办法运用EventBus,索引将不会收效。

stick 事情

  • stick 事情?
    stick 事情便是假如某个目标的stick 事情被发布后,该目标的stick订阅事情没有注册到EvnetBus上,当该目标的stick订阅事情注册到EventBus上时, 该目标的订阅事情将当即被履行。

  • 怎么订阅stick 事情
    在订阅事情时将sticky设置为 truesticky = true

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void subMessageOne(MessageObjectOne msgOne) {
        Log.d(TAG, "subMessageOne: " + msgOne.getInfo());
    }
    
  • 发布stick 事情

    MessageObjectOne object = new MessageObjectOne();
    object.setInfo("hello world");
    EventBus.getDefault().postSticky(object);
    

深化一点

上面介绍了比较简单的是运用,EventBus 运用是比较灵敏的,下面以运用节点进一步解说。

  • 注册
    官方文档中的示例如下:

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

    重官方给出的示例中是在onStartonStop中进行注册和刊出, 其实这仅仅其间的一个运用场景, 不必纠结在什么地方注册和刊出,了解原理依据需求灵敏运用。

    注册的是什么?
    从注册办法中能够看到register办法中传入的是一个目标。经过检查源码知道,注册时经过反射获取到订阅的事情(假如运用索引,从索引类中获取),也便是说,任何目标只要目标中订阅了事情,就会把订阅的事情注册到EventBus中。

    如下示例:将一个一般目标注册到EventBus 中

    public class EventHandler {
        private static final String TAG = "EventHandler";
        @Subscribe
        public void text(MessageObject object) {
            Log.d(TAG, "text: " + object.getInfo());
        }
    }
    EventHandler mHandler = new EventHandler(); 
    EventBus.getDefault().register(mHandler); // 注册
    EventBus.getDefault().unregister(mHandler); // 刊出
    

    注册后,假如发布这个类型的音讯,这个类中订阅的事情就会呼应。不用的时分刊出一下就能够了。

  • 订阅事情
    在EventBus3.0中订阅事情运用注解@Subscribe,所以能够随意命名。事情参数必须只要一个参数。

    不同音讯的订阅
    EventBus是依据事情音讯参数的类型进行分发相呼应的,也便是说,post一种类型的音讯,只要订阅相同音讯的订阅事情才能呼应。如下订阅事情代码示例:

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void subMessageOne(MessageObjectOne msgOne) {
        Log.d(TAG, "subMessageOne: " + msgOne.getInfo());
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void subMessageTwo(MessageObjectTwo msgTwo) {
        Log.d(TAG, "subMessageTwo: " + msgTwo.getInfo());
    }
    

    运用下面办法发送音讯将只要subMessageOne订阅事情得到呼应

    MessageObjectOne object = new MessageObjectOne();
    object.setInfo("hello world");
    EventBus.getDefault().post(object);