EventBus的使用

来源:互联网 发布:工商管理网络课程 编辑:程序博客网 时间:2024/06/05 04:51

基本使用:

1.   首先在接收消息的方法中注册EventBUs:

//只能单例模式注册,     new 的话不能接受消息
//       EventBus.getDefault().register(this);

EventBus.getDefault()其实就是个单例,和我们传统的getInstance一个意思.

2.   然后创建方法来接受接收和处理事件:

@Subscribe//这个必须存在,不然程序会崩,或接收不到消息

public void getEventData(FirstEvent event){

event.getName();

event.getAge();

…..

}

3.   onDestry()方法中注销EventBus

EventBus.getDefault().unregister(this);

4.   发送消息

EventBus.getDefault().post(newFirstEvent(“张三”,20));

粘性事件使用:

在注册之前可以使用:EventBus.getDefaule().postSticky(new FirstEvent(“李四”,19));预先发送消息.

然后如果谁想要将接受这个消息,就来注册,然后通过方法接受消息就可以了. Sticky=true才可以接收消息.

@Subscribe (Sticky=true)//这个必须存在,不然程序会崩,或接收不到消息

public void getEventData(FirstEvent event){

event.getName();

event.getAge();

…..

}

后续使用都一样.

 

ThreadMode的使用

@Subscribe(threadMode =ThreadMode.MainThread) //ui线程执行

public voidonUserEvent(UserEventevent) {

       log(event.message);

    }

   

其中ThreadMode提供了四个常量:

MainThread 主线程

BackgroundThread 后台线程

Async 后台线程

PostThread 发送线程(默认)

 

PostThread:
直接反射调用;也就是说在当前的线程直接调用该方法;你发送消息的地方是子线程,接收消息的地方就是子线程;你发送消息的地方是主线程,接受消息的地方就是主线程,这样可以直接更新Ui.

MainThread:

首先去判断当前如果是UI线程,则直接调用;否则: mainThreadPoster.enqueue(subscription,event);把当前的方法加入到队列,然后直接通过handler去发送一个消息,在handlerhandleMessage中,去执行我们的方法。说白了就是通过Handler去发送消息,然后执行的。

 BackgroundThread:

如果当前非UI线程,则直接调用,和你发送消息的线程是在同一个线程;如果是UI线程,则将任务加入到后台的一个队列,最终由Eventbus中的一个线程池去调用,也就是将会开启一个新的线程来处理消息.

Async:

将任务加入到后台的一个队列,最终由Eventbus中的一个线程池去调用;也就是无论你发送消息的线程是子还是主线程,都会重新开启一个子线程来处理消息,线程池与BackgroundThread用的是同一个。

这么说BackgroundThreadAsync有什么区别呢?

 

BackgroundThread中的任务,一个接着一个去调用,中间使用了一个布尔型变量handlerActive进行的控制。会阻塞线程.

Async则会动态控制并发

 

EventBus3.0有以下四种ThreadMode

  • POSTING(默认):如果使用事件处理函数指定了线程模型为POSTING,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为POSTING的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。
  • MAIN: 
    事件的处理会在UI线程中执行。事件处理时间不能太长,长了会ANR的。
  • BACKGROUND:如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作。
  • ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。

 

添加processor

按照Markus Junginger的说法(EventBus创作者),在3.0中,如果你想进一步提升你的app的性能,你需要添加:

provided 'de.greenrobot:eventbus-annotation-processor:3.0.0-beta1'

 

优缺点:

1.        EventBusgreenrobot公司出的另一款开源框架,这个框架是针对针对Android优化的发布/订阅事件总线,使用EventBus可以极大的减少我们程序的耦合度。

2.      调度灵活。不依赖于 Context,使用时无需像广播一样关注 Context 的注入与传递。

3.      使用简单。

4.        快速且轻量。

5.        完全解耦了请求链之间的关系,避免了请求者被长持有,

6.        又比广播更轻量,比LocalBroadcast则更强大,

7.        可以定义在调用线程、主线程、后台线程、异步。

缺点

1.        各种Event的定义工作量大。每次传的内容不一样,就需要重新定义一个JavaBean

2.        3.0之前限定了方法名(3.0已经可以自定义方法名)

 

自拟面试题:

1.        说说你对EventBus的了解:

以往咱们在Fragment或Activity之间传值的时候,有时候可能用一些静态方法,

当时使用static修饰的方法或属性的生命周期和跟随当前类,直到当前类彻底被回收的时候,static修饰的方法或属性才会被销毁,比较占用内存,容易造成oom,也会导致手机卡顿;也有使用接口回调的,但是Activity把值传给Fragment的时候使用接口回调又不能直接new,如果使用static又会出现上面的情况.但是使用了EventBus以后,才了解了EventBus,它把注册,发送,接收的方法都封装的很简洁,相对于以往的广播,观察者,接口回调等,使用起来更加方便;传送的内容,是根据自定义的JavaBean来生成,需要传什么内容,就在Javabean创建什么属性,使用起来更加方便,随意,实用性很高,而且耦合度很低,不会浪费内存!同时JavaBean也有他的弊端,上面提到了,传的内容都是自定义JavaBean,所有我们每次传内容的时候都需要创建一个Javabean,工程比较大的时候,这样的JavaBean就会创建很多,工作量比较大.还有就是在EventBus3.0版本之前,控制线程的时候都是根据名字来识别,不过在EventBus3.0之后这个Bug已经被修复,名字可以自定义,只要增加注解@Subscribe就可以.

 

2.        EventBus在接受消息时,线程时怎么处理的:

                   PostThread:
直接反射调用;也就是说在当前的线程直接调用该方法;你发送消息的地方是子线程,接收消息的地方就是子线程;你发送消息的地方是主线程,接受消息的地方就是主线程,这样可以直接更新Ui.

MainThread:

首先去判断当前如果是UI线程,则直接调用;否则就通过Handler去发送消息,然后执行相关操作。

 BackgroundThread:

如果当前非UI线程,则直接调用,和你发送消息的线程是在同一个线程;如果是UI线程将会开启一个新的线程来处理消息.

Async:

将任务加入到后台的一个队列,最终由Eventbus中的一个线程池去调用;也就是无论你发送消息的线程是子还是主线程,都会重新开启一个子线程来处理消息。

使用链接

Logger依赖库:

compile 'com.orhanobut:logger:1.15'

EventBus依赖库:

compile 'org.greenrobot:eventbus:3.0.0'

//简单使用

http://blog.csdn.net/qq_35045932/article/details/53130317

//大神深入讲解

http://blog.csdn.net/io_field/article/details/52185717

常见Bug:

粘性事件使用的时候:先寻找控件,然后再注册EventBus接受消息,否则会造成控件空指针有异常.

 

接受消息这里自定义的方法记得添加注解@Subscribe,否则不能接受消息