Android - EventBus 最最最基本使用

原创
01/24 19:59
阅读数 1K

背景

Android开发中数据传递的方式有很多种,常见的有

  • Intent在页面间传递数据
  • Handler刷新UI
  • Broadcast传递消息

系统提供的API在使用上会有些复杂。
举个示例:Handler发送数据并刷新UI

Handler mHandler = new Handler() {
   
   
   

        @Override
        public void handleMessage(Message msg) {
   
   
   
            super.handleMessage(msg);
            switch (msg.what) {
   
   
   
                case 0:
                    // 完成主界面更新,拿到数据
                    String data = (String) msg.obj;
                    textView.setText(data);
                    break;
                default:
                    break;
            }
        }
    };

private void getDataFromNet() {
   
   
   
        new Thread(new Runnable() {
   
   
   

            @Override
            public void run() {
   
   
   
                //耗时操作,完成之后发送消息给Handler,完成UI更新;
                mHandler.sendEmptyMessage(0);

                //需要数据传递,用下面方法;
                Message msg = new Message();

                //可以是基本类型,可以是对象,可以是List、map等;
                msg.obj = "网络数据";
                mHandler.sendMessage(msg);
            }

        }).start();
    }

下面是EventBus简单使用的伪代码

// 注册
EventBus.getDefault().register(this);

// 注销
EventBus.getDefault().unregister(this);

// 发送 MessageEvent 事件
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

// 接收 MessageEvent 事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
   
   
   
    Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

当然,EventBus的出现不是为了取代系统API,只是给我们提供了更多的选择。
在系统API能轻松实现的情况下,就没必要引入EventBus了,虽然它只有60k

接下来我们需要对EventBus进行更进一步的了解,才能更好地使用。

定义

EventBus GitHub 地址

EventBus 是一个事件发布/订阅轻量级框架。相关的发布订阅可参考:发布订阅-维基百科
关于观察者模式和发布订阅模式的谈论,可查看知乎这篇文章。
EventBus的事件发布者不会将事件直接发给订阅者,而是将发布的事件分为不同的类型,订阅者可以选择只感兴趣的事件订阅。
使用过EventBus的朋友回忆一下,确实是如此。没使用过EventBus的朋友可以耐心往下看。

它有以下优点:

  • 能够简化组件间的通信
  • 有效地将事件发送者和订阅者解耦
  • 能避免复杂的依赖性和生命周期问题
  • Fragment,Activity,Service, 后台线程之间传递数据,性能更好。

EventBus 可以代替Android传统的Intent,Handler,Broadcast 或接口函数,

基本使用

使用步骤分为下面几步:

  • 引入依赖
  • 定义事件对象
  • 事件订阅和解除订阅
  • 发送事件

引入依赖

implementation 'org.greenrobot:eventbus:3.1.1'

定义事件对象

public class MessageEvent {

    public final String message;

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

事件订阅

事件不可重复订阅,一般我们在onCreate或者onStart方法中订阅

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

解除事件订阅

事件不可重复解除订阅,一般我们在onStop或者onDestory方法中解除订阅

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

发送事件

  • 普通事件:需要先注册事件才能接收到已发出的事件
  • 粘性事件:事件不需要提前注册也能接收到。

比如:A 页面跳转 B 页面传递参数hello
如果传递参数时使用粘性事件,也就是在A页面发送数据,在B页面注册事件。且接收粘性事件,那么B可以接收到参数hello
如果传递参数时使用普通事件,那么B可以接收不到参数hello。因为普通参数需要注册才能收到消息。

接下来看普通事件和粘性事件的使用。

普通事件

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

// 在主线程展示 Toast 结果
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

粘性事件

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));

// 在主线程刷新 UI
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}


// 移除粘性事件
MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);
// Better check that an event was actually posted before
if(stickyEvent != null) {
    // 移除某个事件
    EventBus.getDefault().removeStickyEvent(stickyEvent);
    // Now do something with it
}


// 移除全部事件
EventBus.getDefault().removeAllStickyEvents();

在接收数据时我们可以看到threadMode = ThreadMode.MAIN指定了线程环境,EventBus还提供了其他四种线程环境。

设置线程环境

  • ThreadMode.POSTING,This is the default,和发布者处在同一个线程,避免线程阻塞
  • ThreadMode.MAIN,UI 线程,避免线程阻塞
  • ThreadMode.MAIN_ORDERED,called in Android’s main thread,有顺序的订阅,避免线程阻塞
  • ThreadMode.BACKGROUND,called in a background thread. 单后台线程,也是需要避免线程阻塞
  • ThreadMode.ASYNC,called in a separate thread,使用场景,网络请求,内部使用线程池去维护

设置事件优先级

事件的优先级类似广播的优先级,优先级越高优先获得消息。默认优先级是0

//在 ui 线程执行 优先级 100
@Subscribe(threadMode = ThreadMode.MAIN, priority = 100)
public void onDataSynEvent(DataSynEvent event) {
    Log.e(TAG, "event---->" + event.getCount());
}

总结

EventBus的基本使用还是很简单的,主要分为三步

  • 引入依赖
  • 注册事件和接收事件
  • 发送事件

注册事件需要和注销事件成对出现,否则会内存泄露。
而且注册事件要在onCreate或者onStart生命周期中注册,注销事件在onStop或者onDestory方法中。

发送事件分为普通事件和粘性事件。

  • 普通事件只能在事件注册之后才能收到。
  • 粘性事件能确保事件注册之后一定能接收到,粘性事件如果不需要了记得要移除。
  • 粘性事件的移除又分为单个事件移除和全部事件移除。

END~

本文同步分享在 博客“_龙衣”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部