EventBus的详细使用攻略

简介

EventBus是针一款Android的发布/订阅事件总线。它能让我们很轻松优雅的在各个组件间传递信息,甚至是线程间的消息传递,而且代码耦合低。

使用

  • 项目中引用,现在最新版本是3.0.0
compile 'org.greenrobot:eventbus:3.0.0'
  • 定义消息类
public class FirstEvent {

    private String msg;

    public FirstEvent(String msg) {
        this.msg = msg;
    }

    public String getMsg() { return this.msg; }

}
  • 订阅事件
EventBus.getDefault().register(this);
  • 发送事件
EventBus.getDefault().post(new FirstEvent("post first event"));
  • 处理事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(FirstEvent firstEvent) {
    Toast.makeText(this, "receive msg-->" + firstEvent.getMsg(), Toast.LENGTH_SHORT).show();
}
  • 取消订阅事件
EventBus.getDefault().unregister(this);

注意

  • EventBus3.0以后采用了注解的方式,处理事件的方法名字可以任意取名字,但是要加注解@Subscribe,后面的threadMode为线程模型。
  • 事件处理函数的访问权限必须为public

EventBus的线程模型

EventBus的事件处理函数需要指定线程模型,也就是指定处理函数运行的线程。一共有四种线程模型:ThreadMode.POSTING、ThreadMode.MAIN、ThreadMode.BACKGROUND与ThreadMode.ASYNC。

  • ThreadMode.POSTING:事件处理函数和发布事件在同一个线程,即事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行。在线程模型为PostThread的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
  • ThreadMode.MAIN:不论事件是在哪个线程中发布出来的,该事件处理函数都会在UI线程中执行。该方法可以用来更新UI,但是不能处理耗时操作。
  • ThreadMode.BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
  • ThreadMode.ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行。同样,此事件处理函数中禁止进行UI更新操作。

示例

事件处理函数
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEventMain(FirstEvent firstEvent) {
    Log.e("ThreadModeMain-->", Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessageEventAsync(FirstEvent firstEvent) {
    Log.e("ThreadModeAsync-->", Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessageEventBackground(FirstEvent firstEvent) {
    Log.e("ThreadModeBackground-->", Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessageEventPosting(FirstEvent firstEvent) {
    Log.e("ThreadModePosting-->", Thread.currentThread().getName());
}
从UI线程发送事件
  • 发送事件
btn_button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        EventBus.getDefault().post(new FirstEvent("send msg"));
    }
});
  • 输出Log:
07-07 17:05:46.709 26041-26041/com.xxq2dream.explorer E/post event-->: main
07-07 17:05:46.711 26041-26041/com.xxq2dream.explorer E/ThreadModeMain-->: main
07-07 17:05:46.711 26041-26765/com.xxq2dream.explorer E/ThreadModeAsync-->: pool-1-thread-1
07-07 17:05:46.711 26041-26041/com.xxq2dream.explorer E/ThreadModePosting-->: main
07-07 17:05:46.712 26041-26766/com.xxq2dream.explorer E/ThreadModeBackground-->: pool-1-thread-2
  • 可以看出POSTING和MAIN的处理函数和发送事件的线程一样,都在UI线程,ASYNC的线程处理函数在新线程pool-1-thread-1,BACKGROUND的线程处理函数在新线程pool-1-thread-2
从子线程发送事件
  • 发送事件
btn_button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new FirstEvent("send msg"));
            }
        });

    }
});
  • 输出Log
07-07 17:10:02.560 29408-29809/com.xxq2dream.explorer E/post event-->: Thread-20772
07-07 17:10:02.563 29408-29809/com.xxq2dream.explorer E/ThreadModeBackground-->: Thread-20772
07-07 17:10:02.563 29408-29809/com.xxq2dream.explorer E/ThreadModePosting-->: Thread-20772
07-07 17:10:02.564 29408-29810/com.xxq2dream.explorer E/ThreadModeAsync-->: pool-1-thread-1
07-07 17:10:02.570 29408-29408/com.xxq2dream.explorer E/ThreadModeMain-->: main

  • 可以看到MAIN的处理函数在UI线程,由于是从子线程发出事件,BACKGROUND和POSTING的线程处理函数都在发出事件的线程中执行,而ASYNC的线程处理函数在新线程pool-1-thread-1中执行

黏性事件

EventBus还支持发送黏性事件。黏性事件就是在发布事件以后再订阅事件,也能收到之前发送的事件。但是,如果在订阅前发送了多个事件,则只能收到最近的一次的发送事件。

示例
  • 首先在未订阅的情况下发送事件
  • 然后订阅后看是否还能收到事件
07-07 17:32:45.511 12248-12248/com.xxq2dream.explorer E/post event-->: main
07-07 17:32:47.474 12248-12248/com.xxq2dream.explorer E/ThreadModeMain-->: main
07-07 17:32:47.474 12248-12423/com.xxq2dream.explorer E/ThreadModeAsync-->: pool-1-thread-1
07-07 17:32:47.474 12248-12248/com.xxq2dream.explorer E/ThreadModePosting-->: main
07-07 17:32:47.475 12248-12424/com.xxq2dream.explorer E/ThreadModeBackground-->: pool-1-thread-2
  • 从Log可以看出订阅后仍然可以收到之前发送的事件
验证只能收到订阅前的最近的一次事件
  • 只要在订阅前发送多次事件,然后订阅以后查看Log即可
07-07 17:41:51.272 16629-16629/com.xxq2dream.explorer E/ThreadModeMain-->: event3
07-07 17:41:51.272 16629-18692/com.xxq2dream.explorer E/ThreadModeAsync-->: event3
07-07 17:41:51.272 16629-16629/com.xxq2dream.explorer E/ThreadModePosting-->: event3
07-07 17:41:51.273 16629-18693/com.xxq2dream.explorer E/ThreadModeBackground-->: event3

以上就是EventBus的详细使用攻略啦!



欢迎关注我的公众号,和我一起每天进步一点点!
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值