EventBus的基本用法

Posted by Chejdj Blog on June 19, 2018

EventBus是一个用于简化各个组件比如:Acivity,Fragment,Thread,Service等之间的通信的一个第三方库,我们就不需要使用handler,Intent来写,增加代码的复杂度

EventBus官方介绍

EventBus…

  1. simplifies the communication between components
    decouples event senders and receivers
    performs well with Activities, Fragments, and background threads
    avoids complex and error-prone dependencies and life cycle issues
  2. makes your code simpler
  3. is fast
  4. is tiny (~50k jar)
  5. is proven in practice by apps with 100,000,000+ installs
  6. has advanced features like delivery threads, subscriber priorities, etc.

简单的说就是这个第三方库解耦了事件的发送和接受者,并且在Activities,Fragment和后台线程之间表现的非常好,让代码更加的简洁。
附上官方给的图
图片
Event主要设计到三方:Publisher,Subscriber,EventBus,Event

  1. Publisher
    发送事件的一方
  2. EventBus
    相当于MessageQueue,储存分发Event.
    3.Subscriber
    事件接受者,图中给的要在Subscriber中写onEvent()方法,但是最新的版本已经改成注解就行
  3. Event
    发送的事件,可以各种类型,它是一个普通的Java对象没有什么限制条件,分为两种事件:一般事件和 Sticky 事件,相对于一般事件,Sticky 事件不同之处在于,当事件发布后,再有订阅者开始订阅该类型事件,依然能收到该类型事件最近一个 Sticky 事件。

简单的使用

(1) 引入第三方库
在Gradle文件中implementation 'org.greenrobot:eventbus:3.1.1'
(2) 定义消息类型
只要是一个java对象就行,当然你也可以直接发送String对象也行

1
2
3
4
5
6
7
8
9
10
11
12
public class MsgBean {
    private String msg;
    public MsgBean(String msg){
        this.msg=msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
}

(3) 准备Subscribers
准备订阅者信息,只需要简单的采用@Subscribe+自己写的方法(方法名free)

1
2
3
4
5
6
7
8
9
10
@Subscribe(threadMode = ThreadMode.MAIN)
 public void onMessageEvent(MsgBean event) {
        Log.e("MainActivity",event.getMsg());
        Toast.makeText(this, event.getMsg(), Toast.LENGTH_LONG).show();
  }
// This method will be called when a SomeOtherEvent is posted
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
    doSomethingWith(event);
}

根据事件类型调用相关函数,注意这里面的threadMode一共有5种模式,你可以按照下面的介绍根据自己需求选取
ThreadMode:POSTING
订阅者将处理消息的方法在会在发送消息的线程中运行,默认的形式,因为没有线程的转换所以开销是最小的,在已知的情况下推荐使用,当然使用这个模式也需要要求处理函数不能做耗时的事情,否则会阻塞发送消息线程。

1
2
3
4
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event){
  log(event.message);
}

ThreadMode:MAIN
订阅者将处理消息的方法在主线程中运行(也就是UI线程),当然处理函数也不能做耗时操作,如果发现posting线程在主线程,就会以POSTING方式运行
ThreadMode:MAIN_ORDERED
订阅者将处理信息将按照顺序处理,第一个处理完了,然后开始调用第二个消息的处理,与第一个区别是第一个发送了就处理,并不会等待上一个处理完了再处理
ThreadMode: BACKGROUND
订阅者被调用在后台线程中,如果posting线程不是一个主线程,消息处理函数将会直接以posting模式运行,如果posting线程是主线程,EventBus将依次递送所有事件到单个线程
ThreadMode:ASYNC
事件处理方法被调用在一个分开的线程,独立于posting线程和主线程,使用线程池来处理消息
(4) 注册Subscribers

1
2
3
4
5
6
7
8
9
10
@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}
@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

EventBus.getDefault()获取一个全局的单例EventBus,当然你也可以通过EventBus.builder()来配置以及创建自己的EventBus
(5) 发送事件
EventBus.getDefault().post(new MesgBean("hello world"))
如果发送Sticky 事件
EventBus.getDefault().postSticky(new MesgBean("Hello everyone!"));
如果是接受Sticky事件,需要在准备Subscribe打开开关

1
2
3
4
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}

想要了解更多,可以看下面的文档
官方文档
源码解析