Android事件总线 EventBus 的使用

  • Post author:
  • Post category:其他


本篇文章共同学习EventBus3.0的使用方法。

EventBus 用于发布/订阅事件总线,简化了应用程序内各组件间、组件与后台线程间的通信。优点是开销小,代码更优雅,以及将发送者和接收者解耦。



一、EventBus的三要素

  • Event:事件,可以是任意类型的对象。
  • Subscriber:事件订阅者。被@Subscribe注解的方法即为事件处理方法,并且由参数threadMode指定线程模型(默认为ThreadMode.POSTING),四种线程模型下面会讲到。
  • Publisher:事件发布者,可以在任意线程任意位置发送事件,直接调用EventBus.getDefault().post(event)方法。根据event参数的类型,会自动调用订阅该event的函数。



二、EventBus的四种ThreadMode

  • POSTING(默认)

    发布事件和接收事件在同一个线程。

    事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
  • MAIN:

    事件的处理会在UI线程中执行。

    同样,事件处理时间不能太长,否则会引起ANR。
  • BACKGROUND

    如果发布事件在UI线程,那么接收事件会在新的线程中运行。

    如果发布事件在子线程,那么接收事件在同一线程执行。

    在此事件处理函数中禁止进行UI更新操作。
  • ASYNC

    无论事件在哪个线程发布,接收事件都会在新建的子线程中执行。

    此事件处理函数中禁止进行UI更新操作。



三、EventBus基本用法

  • 添加依赖库
implementation 'org.greenrobot:eventbus:3.1.1'
  • 获取EventBus对象
EventBus.getDefault()
  • 自定义事件类
public class MessageEvent {
    public int event;
    public String message;
    public Object object;

    public MessageEvent(int event) {
        this.event = event;
    }

    public MessageEvent(int event, String message) {
        this.event = event;
        this.message = message;
    }

    public MessageEvent(int event, String message, Object object) {
        this.event = event;
        this.message = message;
        this.object = object;
    }
}
  • 找到订阅时机,注册事件
  EventBus.getDefault().register(subscriber); // subscriber类型是Object,即传入订阅的类
  • 发送事件
EventBus.getDefault().post(messageEvent);
  • 事件处理方法
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEventTest(MessageEvent messageEvent) {
	int event = messageEvent.event;
	// 事件处理...
}
  • 取消事件订阅
  EventBus.getDefault().unregister(subscriber);



四、代码应用

  • 自定义事件类沿用上面的 MessageEvent 类
  • 自定义MyEventBus,集成 注册/注销事件、事件处理方法等。
public class MyEventBus {
    public static final String TAG = "MyEventBus";
    public static MyEventBus instance;
    public static final int EVENT_UPDATE = 1;
    public static MyEventBus getInstance() {
        if (instance == null) {
            synchronized(MyEventBus.class) {
                if (instance == null) {
                    instance = new MyEventBus();
                }
            }
        }
        return instance;
    }

	// 注册事件
    public void register() {
        EventBus.getDefault().register(this);
    }

	// 取消注册事件
    public void unregister() {
        EventBus.getDefault().unregister(this);
    }

    /**
     * 事件处理方法,根据指定的threadMode,将在后台线程执行,因此不能进行UI操作
     */
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventBackground(MessageEvent messageEvent) {
        int event = messageEvent.event;
        switch (event) {
            case EVENT_UPDATE:
            	...
                break;
        }
    }
}
  • 比如在Activity的 onCreate() 注册事件,点击按钮发送事件,onDestroy() 注销事件
    @Override
    protected void onCreate() {
    	MyEventBus.getInstance().register(this);
    }
    
    public void clickPostEvent(View view) {
    	MessageEvent event = new MessageEvent(EmmEventBus.EVENT_UPDATE);
        EventBus.getDefault().post(event);
    }
    
  	@Override
    protected void onDestroy() {
        MyEventBus.getInstance().unregister(this);
    }



五、EventBus3.0粘性事件

除了上面讲的普通事件外,EventBus还支持发送黏性事件,即:发送事件 -> 订阅事件 -> 处理事件。

粘性事件的写法,仅有以下的不同:

// 粘性事件处理方法,增加属性 sticky = true
@Subscribe(threadMode = ThreadMode.BACKGROUND,sticky = true)
public void onEventBackground(MessageEvent messageEvent) {
	...
}

// 发送粘性事件
EventBus.getDefault().postSticky(new MessageEvent(2));



版权声明:本文为JoesaCSDN原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。