EventBus简单实用

2018-08-07  本文已影响37人  gogoingmonkey

简介

EventBus 是一款订阅——发布模式为核心的开源库 ,EventBus翻译过来是事件总线的意思,一个个事件(event)发送到总线上,然后EventBus根据已注册的订阅者(subscribers)来匹配相应的事件,进而把事件传递给订阅者,这个就是典型的观察者模式
EventBus GitHub地址

对比近似功能

对比广播,这个框架的封装了,没有那么重量级吧个人理解差距不大,handler ,startActivityForResult()等。并且这个也和广播类似有个粘性的概念

使用

1.在Android Studio中添加如下依赖:

compile 'org.greenrobot:eventbus:3.0.0'

2.创建事件实体类,事件实体类,就是传递的事件,一个组件向另一个组件发送的信息可以储存在一个类中,该类就是一个事件,会被EventBus发送给订阅者 ,

如果你想发送字符串可以这样设置你的messageEvent构造 string类型:

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

public class MessageEvent {

    private String message;

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

    public String getMessage(){
        return message;
    }
}

3.向EventBus注册,成为订阅者以及解除注册

EventBus.getDefault().register(this);

即可将当前类注册,成为订阅者,即对应观察者模式的“观察者”,一旦有事件发送过来,该观察者就会接收到匹配的事件。通常,在类的初始化时便进行注册,如果是Activity则在onCreate()方法内进行注册。
当订阅者不再需要接受事件的时候,我们需要解除注册,释放内存:

EventBus.getDefault().unregister(this);

4.声明订阅方法
观察者模式,观察者有着一个update()方法,在接收到事件的时候会调用该update()方法,这个方法就是一个订阅方法。在EventBus 3.0中,声明一个订阅方法需要用到@Subscribe注解,因此在订阅者类中添加一个有着@Subscribe注解的方法即可,方法名字可自定义,而且必须是public权限,其方法参数有且只能有一个,另外类型必须为第一步定义好的事件类型(比如上面的MessageEvent),如下所示

@Subscribe 
public void onEvent(MessageEvent event) {
    /* Do something */
}

5.发送事件
与观察者模式对应的,当有事件发生,需要通知观察者的时候,被观察者会调用notifyObservers()方法来通知所有已经注册的观察者,在EventBus中,对观察者模式底层进行了封装,我们只需要调用以下代码就能把事件发送出去:

EventBus.getDefault().post(EventType eventType);

上面的5个步骤就完成了EventBus 订阅发布了,可能大家比较陌生的就是@Subscribe注解

@Subscribe注解

订阅方法,添加了@Subscribe注解,直接看他的代码。按住点进去

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean sticky() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
}

内部有三个成员,分别是threadMode、sticky、priority。

threadMode代表订阅方法所运行的线程,
public enum ThreadMode {
    
    POSTING,
    
    MAIN,
    
    BACKGROUND,

    ASYNC
}

POSTING:表示订阅方法运行在发送事件的线程
MAIN:表示订阅方法运行在UI线程,由于UI线程不能阻塞,因此当使用MAIN的时候,订阅方法不应该耗时过长
BACKGROUND:表示订阅方法运行在后台线程,如果发送的事件线程不是UI线程,那么就使用该线程;如果发送事件的线程是UI线程,那么新建一个后台线程来调用订阅方法
ASYNC:订阅方法与发送事件始终不在同一个线程,即订阅方法始终会使用新的线程来运行。
一般都是下面的方式,因为我们一般都是要更新UI要回到主线程:

/订阅方法,当接收到事件的时候,会调用该方法
    @Subscribe(threadMode = ThreadMode.MAIN)
sticky代表是否是粘性事件,下面再说
priority代表优先级。设置该优先级的目的是,当一个事件有多个订阅者的时候,优先级高的会优先接收到事件。给这个三个成员赋不同的值,能使得订阅方法有着不同的效果。

sticky解释

关于粘性事件,可以参考Android的广播机制,其中有一个粘性广播,粘性广播的意思是:该广播发送后,会保存在内存中,如果后来有注册的Receiver与之匹配,那么该Receiver便会接收到该广播。那么粘性事件同理,在注册之前便把事件发生出去,等到注册之后便会收到最近发送的粘性事件(必须匹配)。注意:只会接收到最近发送的一次粘性事件,之前的会接受不到

如果发送了3个sticky事件,同一个订阅者只会收到最后一个!!!!切记,可以联系观察者模式记忆,观察者是做出三次改变 ,会响应3次,但是这里不会,只会执行最后一次!!!!

结果亲测,版本有限就不贴出了。只会接受到最后发送的粘性事件,在此之前的事件都接收不到!!!

sticky在实际项目中用到的场景

我们公司项目做的基金模块页面就是顶部有多个tab 没个tab 的头部都有一个基金购买风险的提示,用户在这6个tab 每个页面是不同的,但是都存在这个,现在需求就是我点击任意页面的提示 表明我知道这个事情了,然后在其他5个页面都不显示了,这个时候就用的是sticky发送事件

上一篇下一篇

猜你喜欢

热点阅读