EventBus3.0的使用

来源:互联网 发布:程序员口号大全 编辑:程序博客网 时间:2024/05/19 16:22


前言:

EventBus是最近接手的一个项目上在用的开源库,但是我这个EventBus菜鸟,之前还没用过,还没好好感受过它的好处,前几天刚刚看完源码,对EventBus有了一个大体的了解,看完源码之后,感觉此库真是好处多多啊,不吹不黑,不服来辩,哈哈哈,不吹了,根据官方doc,记录一下EventBus的使用。

优势:

使用一个开源库,我们总要知道他的优势所在,要不然那么多开源库,为毛非要用这个,你说是这个理不。那我们就看一下他的优势所在,
想知道官方的介绍的可以去这里查看:EventBus官方介绍

EventBus是安卓发布/订阅事件总线的优化

翻译过来其实也就这么核心几条:

1. 简化组件间的通信
(1).对发送和接受事件解耦
(2).可以在Activity,Fragment,和后台线程间执行
(3).避免了复杂的和容易出错的依赖和生命周期问题
2. 让你的代码更简洁
3. 更快
4. 更轻量(jar包小于50K)
5. 实践证明已经有一亿多的APP中集成了EventBus
6. 拥有先进的功能比如线程分发,用户优先级等等

基本结构:

盗图一张:

基本用法:

1. 添加gradle依赖compile 'org.greenrobot:eventbus:3.0.0'

Step 1: Define events

Events 就是一个普通的JavaBean,没有任何特殊要求,例如:

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

Step 2: Prepare subscribers

准备subcriber的回调method,来处理post event,从EventBus_3开始,用注解@Subscribe来定义subscriber的回调method,方法名可以任意定义
例如:

 // This method will be called when a MessageEvent is posted    @Subscribe    public void onMessageEvent(MessageEvent event){        Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();    }    // This method will be called when a SomeOtherEvent is posted    @Subscribe    public void handleSomethingElse(SomeOtherEvent event){        doSomethingWith(event);    }

Subscribers与BroadcastReceiver类似,需要register和unregister,只有注册了EventBus,回调方法才起作用,在Android中,一般与Activity的生命周期绑定在一起

官方demo:

@Overridepublic void onStart() {    super.onStart();    EventBus.getDefault().register(this);}@Overridepublic void onStop() {    EventBus.getDefault().unregister(this);    super.onStop();}

Step 3: Post events

前面准备好,这里就可以任意post event。所有已注册EventBus的subscriber只要event_type相匹配,都可以收到该event

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

ThreadMode用法:

当牵扯到线程间通讯时,特别是,主线程,后台线程,耗时操作线程,等线程间的通讯时,我们就必须倍加小心,好在EventBus很强大,已经考虑到了,我们只需要根据具体的需求去配置,不同的线程模式ThreadMode即可:

ThreadMode源码:

public enum ThreadMode {    POSTING,    MAIN,    BACKGROUND,    ASYNC;}

接着,逐一分析下,各个模式适合的场景:

POSTING

这个模式最简单,也是EventBus默认的模式,也就是说:post event和handle event在同一个线程@Subscribe(threadMode = ThreadMode.POSTING) // ThreadMode is optional here//默认为Posting,可以不指定public void onMessage(MessageEvent event) {    log(event.message);}

MAIN


当指定threadMode=Main时,此时,handle event是运行在UI线程的,如果,post event也是在UI线程,就跟Posting模式一样,Warning:使用此模式,不能堵塞UI线程// Called in Android UI's main thread@Subscribe(threadMode = ThreadMode.MAIN)public void onMessage(MessageEvent event) {    textField.setText(event.message);}

BACKGROUND

当指定threadMode=Background时,如果 post event不在UI线程,那么handle event 会在此线程回调;如果 post event在UI线程,EventBus使用一个后台线程,按顺序分发所有事件。Warning:使用此模式,不能堵塞后台线程// Called in the background thread@Subscribe(threadMode = ThreadMode.BACKGROUND)public void onMessage(MessageEvent event){    saveToDisk(event.message);}

ASYNC

当指定threadMode=Async时,handle event始终独立于UI线程和post event所在的线程,即:和post event 不在同一线程,也不在UI线程。此模式适合耗时任务:e.g.:网络链接。Warning:避免触发大量的长时间运行的异步线程,来限制并发线程的数量。EventBus使用Thread pool高效 的使用线程// Called in a separate thread@Subscribe(threadMode = ThreadMode.ASYNC)public void onMessage(MessageEvent event){    backend.send(event.message);}

Configuration用法:

当默认的EventBus不足以满足需求时,EventBusBuilder就上场了,EventBusBuilder允许配置各种需求的EventBus

例如1:当没有subscribers的时候,eventbus保持静默:EventBus eventBus = EventBus.builder().logNoSubscriberMessages(false)    .sendNoSubscriberEvent(false).build();例如2:配置异常:默认情况下:eventbus捕获onevent抛出的异常,并且发送一个SubscriberExceptionEvent 可能不必处理EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();

配置默认的eventbus单例

官方推荐:在application类中,配置eventbus单例,保证eventbus的统一

例如:配置eventbus 只在DEBUG模式下,抛出异常,便于自测,同时又不会导致release环境的app崩溃EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();

Sticky Events用法:

前面说的一般的post event,正常流程,必须是先register,然后post event,handle event才能起作用。但是当我们post event时,还没有subcriber怎么办?但是又想后注册的subscriber,能收到消息,这时sticky event就开始大显身手了。

Warning:EventBus会把最后一个sticky event记录在内存中,然后分发给subscriber

来看下官方的Demo

1 post sticky event:EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));2 启动一个新的Activity,准备subscriber,注册后,所有的sticky subscriber的回调方法,会马上获得之前的sticky event@Overridepublic void onStart() {    super.onStart();    EventBus.getDefault().register(this);}//注意这里sticky=true@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)public void onEvent(MessageEvent event) {    // UI updates must run on MainThread    textField.setText(event.message);}@Overridepublic void onStop() {    EventBus.getDefault().unregister(this);    super.onStop();}

Getting and Removing sticky Events manually

如上所述,当subscriber注册后,最后一个sticky event会自动匹配。但是,有些时候,主动去检查sticky event会更方便,并且 sticky event 需要remove,阻断继续传递。

官方demo

//返回的是之前的sticky eventMessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);// Better check that an event was actually posted beforeif(stickyEvent != null) {    // Now do something with it}

2中sticky event使用方法都可行,看业务需要和个人习惯,选择合适的使用方法

Priorities and Event Cancellation用法:

大多数情况下,eventbus不需要改变线程优先级,或者取消event,但是不排除少数情况,需要改变线程优先级。

Subscriber Priorities

官方demo

//priority默认为0,不同ThreadMode下的分发流程不受优先级的影响//优先级高的可以优先获得消息@Subscribe(priority = 1);public void onEvent(MessageEvent event) {…}

Cancelling event delivery

如果,不希望后续的subcriber收到消息,可以在收到消息后,调用cancelEventDelivery(Object event) 取消消息的后续传递。

官方demo

@Subscribepublic void onEvent(MessageEvent event){// Process the event…EventBus.getDefault().cancelEventDelivery(event) ;}

Note:一般情况下,event的取消发生在高优先级的subscriber

ProGuard 混淆规则

-keepattributes *Annotation*-keepclassmembers class ** {    @org.greenrobot.eventbus.Subscribe <methods>;}-keep enum org.greenrobot.eventbus.ThreadMode { *; }# Only required if you use AsyncExecutor-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {    <init>(java.lang.Throwable);}

AsyncExecutor

关于AsyncExecutor的用法,还是看官方文档吧,因为这个我也没用过

Subscriber Index

这是eventbus3.0新增的功能,是对原有功能的优化,为register提供了一种比反射更快速的方案,也就是对应源码中的private List findUsingInfo(Class

原创粉丝点击