Eventbus收录

Eventbus收录同一个onEvent函数不能被注册两次,所以不能在一个类中注册同时还在父类中注册。 消息的接收是根据参数中的类名来决定执行哪一个接收处理方法的。即:订阅者的处理方法是根据订阅事件的类型来确定订阅函数的。 每个事件可以有多个订阅者。 当Post一个事件时,这个事件类的父类的事件也…

Eventbus收录

EventBus优缺点:

优点:简化组件之间的通信方式,实现解耦让业务代码更加简洁,可以动态设置事件处理线程以及优先级

缺点:目前发现唯一的缺点就是类似之前策略模式一样的诟病,每个事件都必须自定义一个事件类,造成事件类太多,无形中加大了维护成本

概述:

EventBus是一款针对Android优化的发布/订阅(publish/subscribe)事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。简化了应用程序内各组件间、组件与后台线程间的通信。优点是开销小,代码更优雅。以及将发送者和接收者解耦。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。

EventBus 三个主要的元素:

Event:事件。可以是任意类型的对象

Subscriber:事件订阅者onEvent,onEventMainThread,onEventBackgroundThread,

onEventAsync ,EventBus 3.0 函数名字不再受到权限

Publisher:事件发布者,可以在任意线程任意位置发送事件

关于ThreadMode:

onEvent: 如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。

onEventMainThread: 如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。

onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。

onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync。

  • NAIN UI主线程
  • BACKGROUND 后台线程
  • POSTING 和发布者处在同一个线程
  • ASYNC 异步线程

基本用法:

  • 引入EventBus:
compile 'org.greenrobot:eventbus:3.0.0'
  • 定义事件:
public class MessageEvent { /* Additional fields if needed */ }
  • 注册事件接收者:
eventBus.register(this);
  • 发送事件:
eventBus.post(event)
  • 接收消息并处理:
public void onEvent(MessageEvent event) {}
  • 终止事件往下传递
EventBus.getDefault().cancelEventDelivery(event) ;//优先级高的订阅者可以终止事件往下传递
  • 注销事件接收:
eventBus.unregister(this);
  • 混淆

-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);
}
  • 最后,proguard 需要做一些额外处理:
#EventBus
 -keepclassmembers class ** {
    public void onEvent*(**);
    void onEvent*(**);
 }

EventBus的粘性事件:

通俗讲是当前页把一个Event发送到一个还没有初始化的Activity/Fragment,即尚未订阅事件。那么如果只是简单的post一个事件,那么是无法收到的,这时候,你需要用到粘性事件,它可以帮你解决这类问题.

  • 粘性事件的发布:
EventBus.getDefault().postSticky("RECOGNIZE_SONG");
  • 粘性事件的接收
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void receiveSoundRecongnizedmsg(String insType) {
        if ("RECOGNIZE_SONG".equals(insType)) {
            soundRecognizeCtrl();
        }
    }

注意项

  1. 同一个onEvent函数不能被注册两次,所以不能在一个类中注册同时还在父类中注册。

  2. 消息的接收是根据参数中的类名来决定执行哪一个接收处理方法的。即:订阅者的处理方法是根据订阅事件的类型来确定订阅函数的。

  3. 每个事件可以有多个订阅者。

  4. 当Post一个事件时,这个事件类的父类的事件也会被Post。

  5. 所有事件处理方法必需是public void类型的,并且只有一个参数表示EventType。

EventBus 3.0 与2.x的区别

EventBus 2.x 必须定义以onEvent开头的几个方法,代码中语境比较突兀,且有可能会导致拼写错误,例如数据同步事件

EventBus 3.0 函数名字不再受到权限,而且可以在一个函数中体现出在哪个线程执行,并且可指定接收事件的优先级

EventBus 2.x 注册方式也比较繁琐

EventBus 3.0 注册方式只有一个

EventBus 3.0 性能更优

EventBus 2.x 是采用反射的方式对整个注册的类的所有方法进行扫描来完成注册,当然会有性能上的影响。EventBus 3.0中EventBus提供了EventBusAnnotationProcessor注解处理器来在编译期通过读取@Subscribe()注解并解析、处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息,这样就比在运行时使用反射来获得这些订阅者的信息速度要快

出现接收不到事件的情况这边遇到过两种情况:

1 在使用Eventbus.getDefault().post(任意事件类型)方法的时候,必须是在注册事件(EventBus.getDefault().register(this);)之后发送事件才可以接收到,否则会出现接收不到的情况,也就是说在发送事件之前,此事件必须已经注册;
针对此问题解决办法:可以使用粘性事件  就是在发送事件的时候使用Eventbus.getDefault().postSticky(),就可以不用关心注册事件是否已经注册;或者注册前后的问题,如果发送粘性事件之前没有入注册事件,事件注册完成就会收到之前发送的粘性事件;

2 接受事件的方法参数事件类型必须为引用数据类型(不能为基本数据类型)例如当中的接收事件的方法 
isPay(Boolean payResult)  方法参数(事件类型)必须为引用数据类型

3 区分不同的事件

EventBus是根据不同的类来区分事件发到哪离去

总结 参考来源

www.cnblogs.com/whoislcj/p/…

mp.weixin.qq.com/s?__biz=MjM…

3.0源码分析

www.jianshu.com/p/f057c460c…

今天的文章Eventbus收录分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/59565.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注