打开EventBus3.0的正确姿势

什么是EventBus

先来一段官方介绍和配图

EventBus is a publish/subscribe event bus optimized for Android.

打开EventBus3.0的正确姿势_第1张图片

就是说EventBus是一个针对Android优化的发布/订阅事件总线。它可以做到:

  • 简化组件之间的通信
  • 简化代码结构
  • ……

试想这样一个场景,一个Activity有两个fragment分别是f1, f2。有一个需求就是f1中的一个按钮被点击后改变f2的内容。有两个方法可以完成:

  1. 很暴力的方法,在f1中得到Activity的引用,然后通过Activity的到f2的引用从而调用f2的方法。
  2. f1定义一个接口,让Activity实现,从而让Activity调用f2的方法。
    第一个方法将f1和Activity完全耦合起来,f1失去了独立性和复用性。推荐第二个方法,让f1和Activity解耦。

EventBus可以在开销小、代码优雅的同时解耦事件发布者和订阅者。

基本使用

注册

在Activity或者Fragment的onCreate()方法中注册EventBus

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }

在onDestroy()方法中取消注册

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

发布事件

通过post发布一个事件,传递一个我们自己定义的类

public class SampleEvent {

    private String info;

    public DelayEvent(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }
}
EventBus.getDefault().post(new SampleEvent(Item.items));

这样就完成了事件发布

订阅事件

订阅事件也就是处理事件,我们需要自己写一个处理事件的方法,参数必须是该事件的类型。

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void handleSampleEvent(SampleEvent event) {
        Log.d(TAG, event.getInfo());
    }

该方法必须有一个Subscribe注解表示这是一个订阅事件的方法,threadMode指的是该方法在那个线程调用,有如下四种:

  • Thread.POSTING:在发送事件的线程调用,默认就是这个。
  • ThreadMode: MAIN:在主线程执行。
  • ThreadMode: BACKGROUND:如果发布线程是主线程,那就创建新线程执行,否则直接在发布线程执行。
  • ThreadMode: ASYNC:开启新线程,不依赖主线程和发布线程,这样发布方就不需要等待事件处理结束(若是在发布线程执行,肯定会阻塞该线程的),适用于耗时的任务。

总流程

看了上面的过程有可能会疑惑事件是怎么发布出去的,又是怎么得到的。其实在注册的时候EventBus就会通过反射得到该类下有@Subscribe的注解方法,然后保存起来,包括参数。然后在事件发布的时候去查询是否有参数匹配的(如这里的SampleEvent),匹配到了就调用,一个事件可以很多订阅者。

StickyEvent

SticykEvent叫做粘性事件,普通的事件在发布的时候马上查询是否有匹配,执行所有匹配后就删除该事件。而StickyEvent在EventBus里每一个类对应只有一个,也就是说会覆盖,假设多次发送粘性事件SampleEvent,最新的总是覆盖以前的,而且会被缓存下来不会删除。对应的订阅者也不一定要在发布之前订阅,因为粘性事件会被缓存,所以在发布后订阅也是一样的。

EventBus.getDefault().postSticky(new SampleEvent("1"));
EventBus.getDefault().postSticky(new SampleEvent("2"));
startActivity(new Intent(getActivity(), SecondActivity.class));
    // SecondActivity.java
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onDelayEvent(DelayEvent event) {
        Toast.makeText(SecondActivity.this, "dalay event:" + event.getInfo(), Toast.LENGTH_SHORT).show();
    }

通过postSticky()发布,订阅需要注解sticky = true。
因为接受的粘性事件,所以这里订阅是在发布之后也可以收到,收到的只有一个,也就是第二个发出的SampleEvent

ventBus.getDefault().postSticky(new SampleEvent("2"));

你可能感兴趣的:(Android)