EventBus使用过程中,遇到的问题点

来源:互联网 发布:淘宝老客户刷销量 编辑:程序博客网 时间:2024/06/05 04:48

说到EventBus,想必大家都不陌生,咦~~~~你没听过,好吧,你还要认真学习啊,这篇博客不是去分析EventBus的源码的,也不是讲什么人生哲理,就是教大家如何使用这么一个神器,以后谁要是问你Eventbus会不会用。。。你就可以骄傲的炫耀你的车技了,并将他领上车

1.初步理解

好了先上一张图体会一下这个的好处,是不是省了很多事,感觉又要复制粘贴一段话,放在下面,每次复制粘贴都反觉到深深的罪恶感。。。 
这里写图片描述
  EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。 
  顺便粘个源码的地址,我知道你是不会去看的,这是EventBus在GitHub上的开源库地址:https://github.com/greenrobot/EventBus

2.新手入门入门

好了下面直接教大家如何使用 
(1)EventBus配置 
EventBus框架也是采用建造者模式设计的,可以通过EventBusBuilder来设置一些配置信息,例如设置debug模式下要抛出异常

EventBus     eventBus=EventBus.builder().throwSubscriberException(BuildConfig.DEBUG.build();
  • 1
  • 2
  • 1
  • 2

(2)添加引用

compile 'org.greenrobot:eventbus:3.0.0'
  • 1
  • 1

( 3 ) 定义一个事件类型

public class MyEvent {    private String msg;//所要发送的信息内容,你也可以写点别的啥    public MyEvent(String msg) {        this.msg = msg;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(4)订阅/解除订阅

EventBus.getDefault().register(this);//订阅EventBus.getDefault().unregister(this);//解除订阅
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

有人问我这玩意儿放在哪里,好吧,我告诉你放在哪里,首先写一个封装类,

public class EventUtil {//注册事件    public static void register(Object context) {        if (!EventBus.getDefault().isRegistered(context)) {            EventBus.getDefault().register(context);        }    }    //解除    public static void unregister(Object context) {        if (EventBus.getDefault().isRegistered(context)) {            EventBus.getDefault().unregister(context);        }    }    //发送消息    public static void post(Object object) {        EventBus.getDefault().post(object);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

然后如果是Activity内接收消息,就在onCreate和onDestroy中调用,如果是fragment呢,好吧也是还是在这两个方法中。。。。。。。不过就变成了

 EventUtil.register(this);//订阅事件 EventUtil.register(this);//取消事件
  • 1
  • 2
  • 1
  • 2

(5)发布事件

EventBus.getDefault().post(new DataSynEvent());
  • 1
  • 1

(6)订阅事件处理

    @Subscribe(threadMode = ThreadMode.MAIN) //在ui线程执行    public void onDataSynEvent(DataSynEvent event) {    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

ThreadMode总共四个:

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

他们有啥子用呢,其实就是告诉你只有在主线程中才能更新UI,主线程中不要做耗时操作,如果有必要需要和handler一起使用

(7)订阅事件的优先级

说到优先级,其实和Boardcast接收者的优先级差不多,数越大优先级越高,一般0-100吧

 @Subscribe(threadMode = ThreadMode.MAIN,priority = 100) //在ui线程执行 优先级100    public void onDataSynEvent(DataSynEvent event) {    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

有了优先级,有人就该问了,是不是可以对消息进行截获,不让它往下发呢,这个当然可以了

  EventBus.getDefault().cancelEventDelivery(event) ;//优先级高的订阅者可以终止事件往下传递
  • 1
  • 1

(8)EventBus黏性事件

我们在学广播的时候有一种广播叫粘性广播。如果使用普通广播send一个消息,然后在你的onReceive中执行超过10秒的话,这个广播的状态就会变为可以被干掉的状态,而粘性广播就是为了解除这个10秒限制。但是为了安全起见,忘了在哪个版本的SDK把这玩意给废弃掉了。

那么回到我们的问题,当你发送消息的时刻注册消息接收的时刻 并不能确定顺序,比如你请求网络数据订阅事件 同时执行,如果数据返回的特别快呀快,那你 EventUtil.register(this)这句代码还没执行完呀,这时候你就就收不到这个消息了

这个概念这么理解,就像qq邮件里有个订阅的功能,如果你订阅了一个公众邮件, 
那么他们就会给你推送消息,但是你却接收不到你订阅之前他们推送的消息

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //在ui线程执行    public void onDataSynEvent(DataSynEvent event) {    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.4版本的时候有一个发送粘性事件的方法, 后来发现原来3.0还是有这个方法的,所以就这么发送粘性事件

EventBus.getDefault().postSticky(new TestEvent());
  • 1
  • 1

我们知道这个粘性事件是存在静态变量里的,就是如果你不干掉他,他就一直在,这时候需要在的onDestory中调用这个

EventBus.getDefault().removeStickyEvent(new TestEvent());//移除一个EventBus.getDefault().removeAllStickyEvents();//移除全部
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

(9)EventBus processor使用

关于这个东西的使用,我看了一下,哎呀,看不太懂,拜访了鸿洋大神的博客,勉强能理解一点关于这个编译时注解这个东西。。。 
要想深入了解可以点击这个 
http://blog.csdn.net/Tencent_Bugly/article/details/51354693 【腾讯Bugly干货】老司机教你“飙”EventBus3 
这里就教你怎么做就行了:

项目的build.gradle中配置

buildscript {    dependencies {        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

app的build.gradle中配置

apply plugin: 'com.neenbedankt.android-apt'apt {    arguments {        eventBusIndex "com.whoislcj.eventbus.MyEventBusIndex"    }}dependencies {    compile 'org.greenrobot:eventbus:3.0.0'    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

此时编译一次,自动生成生成索引类。在\build\generated\source\apt\PakageName\下看到通过注解分析生成的索引类,这样我们便可以在初始化EventBus时应用我们生成的索引了。

添加索引到EventBus默认的单例中

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();//如果你做了单例的话,放到单例中,如果没有就在Application中放上这句就行了
  • 1
  • 2
  • 1
  • 2

这玩意主要是为了提高这句代码的速度

EventBus.getDefault().register(this);
  • 1
  • 1

(10)代码的混淆

我发现好多人都为这个问题纠结,最后找不到错就直接不混淆了,呵呵呵 
先来个全的

-keepattributes *Annotation*//keep反射-keepclassmembers class * {    @org.greenrobot.eventbus.Subscribe <methods>;//这个牵涉到你的需求如何,如果你使用了EventBus processor进行加速,你就必须加上这个,只要有这个注解的类和方法都不混淆,为反编译提供了便利。。。如果没有用到加速,这个就不用了}-keep enum org.greenrobot.eventbus.ThreadMode { *; }# Only required if you use AsyncExecutor//如果你使用了ASYNC 异步线程-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {    <init>(java.lang.Throwable);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

好了关于Eventbus的使用就这些内容,如果你想再了解一下源码,这里是传送门

http://skykai521.github.io/2016/02/20/EventBus-3-0%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/ EventBus 3.0 源代码分析 
还有这些个网址 
http://www.cnblogs.com/whoislcj/p/5595714.html Android消息传递之EventBus 3.0使用详解(三)

4 0
原创粉丝点击