EventBus2.0-3.0的简单使用与详解

来源:互联网 发布:房产证打印软件 编辑:程序博客网 时间:2024/06/08 20:22

EventBus是一个用于简化Andorid、Fragment、Threads、Service之间信息传递的一个发布/订阅事件集。

EventBus是由大名鼎鼎的greenrobot出品的一个用于Android中事件发布/订阅的库。简单点说就是用于Fragment,Activity,Service,线程之间进行数据传递,它为开发者提供除了 intent、handler、boardcast这几种传递数据的方式之外的一种选择,其优点在于 几乎不怎么消化资源,并且代码优雅简洁。

传统的Android组件之间的通信方式有:Activity之间使用Intent;Service向Activity发送broadcast;Fragment和Activity之间相互持有对方的引用(随后可以调用对方的相关方法进行事件传递)。传统的事件传递的问题在于:通信方式没有实现解耦,是硬编码在组件中的。组件一旦发生修改,对应的通信方式就需要跟着修改。其实不管什么场景下,我们最好能够使得自己编写的代码最大限度的解耦,这是一个很好的习惯,避免无用功,提高代码利用率

使用EventBus的建议:

  • 并不建议将应用中所有的事件都通过EventBus进行发送,尤其对于一对一的组件之间通信,建议不要使用EventBus。EventBus的使用场景更像是一种广播,当我们向EventBus发送一个事件,则该事件将会传递给多个该事件的订阅者,比如Service向Activities发送事件。跟LoacalBroadCast有点近似
  • 在Activity和Fragment中使用EventBus时,要注意在组件的生命周期开始时registered EventBus,在生命周期结束时unregistered EventBus。否则容易导致OOM;
  使用EventBus的好处在于:
  • 简化组件之间的通信方式
  • 让业务代码更加简洁(但是需要配合相应注解进行使用)
  • 可以指定事件处理方法的执行线程,和订阅者的优先级(跟广播类似)
  • 足够的稳定,已经被很多Android应用使用。

//使用Eventbus2.0与3.0的区别

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

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

EventBus 2.x 注册方式也比较繁琐。EventBus  3.0 注册方式只有一个

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

EventBus 四个Subscriber

首先在将四种方式之前不得不说一下ThreadMode, ThreadMode 是EventBus中一个很重要的概念,其本身是一个enum,他同样提供了四个默认属性值:Async,BackgroundThread,MainThread,PostThread;而在3.0中则改为ASYNC,BACKGROUND,MAIN,POSTING。分别对应四个方法。

onEvent
对应 PostThread,当使用onEvent作为订阅函数时,发布者在哪个线程发布事件,onEvent就会在哪个线程接收事件。因为函数执行的线程不确定,这就要求用户 最好不要执行耗时操作,可能会出现线程阻塞或者事件分发不及时的问题。
注意一点:
方法的修饰符 最好 使用 public

onEventMainThread
对应 MainThread,当使用onEventMainThread作为订阅函数时,发布者不管在哪个线程发布事件,onEventMainThread都会在主线程接收事件。这就要求用户 一定不要执行耗时操作,不然会造成线程阻塞。

onEventBackground
对应 BackgroundThread,当使用onEventBackground作为订阅函数时,发布者如果在主线程发布事件,onEventBackground将会新开一个子线程并接收事件,但是如果是在子线程中发布事件,onEventBackground将会直接在该子线程中接受事件。

onEventAsync
对应 Async,当使用onEventAsync作为订阅函数时,发布者无论在哪个线程发布事件,onEventAsync都会新开一个子线程并接收事件。

而相对来说,3.0 改变对需要固定函数名的设定,提供了一种新的形式,改用注解@Subscribe ,在使用中更加灵活,而且 这里 ThreadMode 将被直接使用。EventBus 并没有摒弃固定函数名的形式,开发者仍旧可以使用这种形式,不过在使用过程中必须要 添加注解 @ Subscribe 但不用指定ThreadMode

先谈谈EventsBus2.0的基本使用

//导入依赖

compile 'org.greenrobot:eventbus:3.0.0'

provided 'org.glassfish:javax.annotation:10.0-b28' //解决获取不到@Subscribe注解的问题

//注册EventBus

//注册EventsbusEventBus.getDefault().register(this);
//定义点击事件

//点击跳转@OnClick(R.id.button_jump)public void onViewClicked() {    Intent intent = new Intent(MainActivity.this, Main_jump.class);    startActivity(intent);}
//跳转过去新的Activity.设置点击事件,发布事件

@OnClick(R.id.button_send)//发送的点击事件public void onViewClicked() {    EventBus.getDefault().post(new MessageEvent("今天学习的Eventbus,受益匪浅,需要继续努力。强化自己"));    finish();}
//在MainActivity获取发布的消息

//接受消息public void onEventMainThread(MessageEvent message){        //获取消息    String s = message.getMsg();    textName.setText(s);}
//注销订阅。在生命周期结束时unregistered EventBus。否则容易导致OOM;

@Overrideprotected void onDestroy() {    super.onDestroy();    //反注册    EventBus.getDefault().unregister(this);}
EventsBus3.0的基本使用

3.0 改变对需要固定函数名的设定,提供了一种新的形式,改用注解@Subscribe ,在使用中更加灵活,而且 这里 ThreadMode 将被直接使用。

ThreadMode总共四个:

NAIN UI主线程

BACKGROUND 后台线程

POSTING 和发布者处在同一个线程

ASYNC 异步线程

//注册EventBusEventBus.getDefault().register(this);
//点击事件@OnClick(R.id.button_jump)public void onViewClicked() {    Intent intent=new Intent(MainActivity.this,Mainjump.class);    startActivity(intent);}
//点击事件public void onViewClicked() {    //发送消息    EventBus.getDefault().post(new Bean("xxx"));    finish();}
@Subscribe(threadMode = ThreadMode.MAIN)public void messageEvent(Bean bean){    //获取消息    String s = bean.getName();    textName.setText(s);}
@Override//注销protected void onDestroy() {    super.onDestroy();    EventBus.getDefault().unregister(this);}