专栏首页SpringCloud专栏EventBus如何使用及一些常见场景

EventBus如何使用及一些常见场景

    目前网上有很多的eventbus的教程,本身eventbus使用也比较简单,也没有难以理解的地方,所以我就不多提入门教程了。讲几个场景,使用eventbus后可以使项目更简单,便于快速开发功能。

    至于eventbus的原理和入门实战,可以参考这个帖子http://blog.csdn.net/lmj623565791/article/details/40794879  他的博客里有几篇讲原理的,想了解原理的可以去看看。

    初次使用EventBus时,它的特性是很吸引人的。类似于一个全局的观察者(上帝),你可以把所有的事件触发都交给它,然后可以在任何一个地方来指定事件的触发,它可以跨界面(activity),类似于上帝飘在你的项目的上空,不用再去做大量的引用传递、写回调。它确实简化了一些逻辑。

    简单的例子,你有一个主界面,里面有一些信息可能会修改,但触发源不在该界面,是在其他的界面触发了一些事件后,首页的内容需要做修改。如果没有EventBus,也有很多的方式可以实现,譬如定义全局静态变量、或者onResume时获取触发源的值修改界面值、或者定义个CallBack接口传出去等等。不管怎样,总是要把主页和触发源关联起来,这是相当难受的,不得不写的这个引用让人如鲠在喉。还有activity和fragment传值时那些写法,都是很不爽的。

    如此情况下,你需要EventBus来拯救你。它砍掉了这个连接线,你不需要把需要修改的界面的引用往外传,不需要传任何东西,你只需要在该界面注册EventBus,剩下的事情就交给上帝吧,然后你就可以在上帝提供的方法里尽情的做你的修改,上帝给你提供了几个方法(onEvent),它们是四大金刚onEventPostThread, onEventMainThread,onEventBackgroundThread,onEventAsync。这些方法会自动去触发。当然你得需要先给上帝打个电话告诉他触发点。

    譬如微信首页你有未读消息3个时,界面会有3个小红点点,当你点开一个未读消息后,进入了下个界面,那么此时未读消息就是2了,但你并不在首页了,你需要在你打开消息并阅读完毕后通知首页改成2.这就是一种跨界面修改值。EventBus对这种情况的处理就是,在主页注册EventBus(EventBus.getDefault().register(this);),就是告诉上帝,我把自己交给你了,将来有事就叫我,我在 onEventMainThread()这个方法里等你。然后在第二页,阅读完消息后,触发一个方法(EventBus.getDefault().post(new MyEvent());)相当于给上帝打个电话,说我犯事了,你找人处理吧。此时上帝会去遍历所有注册了EventBus的类,发现了主页君,然后就捅了捅主页君的菊花(onEventMainThread),此时主页君就呻吟了一下,然后在UI上把3变成了2.

相信此时应该明白了EventBus的作用,当然有人会问,那么多界面都注册了EventBus,难道上帝要捅那么多菊花,他怎么知道二页君说的是哪个。可以看一下post方法里的参数,这个就是维系主页和二页的通道了,上帝是通过这个参数来判断的。首页里的这个方法public void onEventMainThread(MyEvent event)里这个参数和post里的参数一样就行了。这个MyEvent不用继承任何类不用实现接口,就是个普通的javaBean(可以携带值),或者就是个空类也行(只做个联系的标记)。还提一个就是可能不只首页要监听第二页的触发,也许有很多个地方(可以不是界面,就一个工具类譬如DB处理类也行)都要监听第二页的触发,那只需要所有监听的都去注册一下自己写明Event是哪个就行了,然后就等着上帝一个一个的捅你菊花就行了。是不是这种感觉很美妙!!!

   由此看来EventBus主要作用就是解耦,把本该有联系的需要传引用的给简化了,由它来分发事件了。在某些时候和Android里的broadcast有点像,都是能通知很多个观察者,只不过更简便一点。

    根据以往做过的一些场景,我觉得有几个地方是非常适合eventbus来处理的。

    一:注册页面,在注册页面填写了手机号、个人信息,传头像操作后,注册成功了,进入了主界面。此时我们需要在主界面关闭之前的注册的所有页面,此时就可以使用eventbus来通知前几个注册用的activity来关闭自己。这样的目的就是当注册失败时,用户按返回键还是能回到填写信息页。当注册成功后,按返回键就直接退出程序,不再保留注册填信息页了。

二:activity和fragment有交互的场景。这个是最常见的,一个activity里有个viewpager包含几个fragment,activity界面上有类似于全选、计算总额等等之类需要和某个或多个fragment通信的,由于这个控件属于activity是个全局的,而数据都在各个fragment里,所以他们之间的相互响应是比较麻烦的。

三:流程跨多个界面的。譬如一次拍照发朋友圈的操作,在第一页可以选择写文字、拍照、打开相册的操作,然后不同的操作决定了几个不同的流程线,期间要经历几个过渡页面(相册页,裁剪页之类的),但最终对于第一页我们关心的其实就是图片的本地地址和文字,中间的过渡页面是没有意义的。但是呢这些过渡页不同的处理又会对第一页产生不同的结果,此时就需要一个完全解耦的eventbus来处理结果。而不能把第一页的某个引用往外传递,要不然会很难处理。

四:观察者中有相对比较独立的处理逻辑时。譬如要做一个文件传输备份的功能,主页上要有个地方显示当前有多少个正在传输之类的,然后在后台某个地方有文件传输的功能正在传文件,此时还有一个类似于第三方监察者来观察这个传输流程(记录传输结果到数据库,传输中断控制等)。这种功能就是一个被观察者(传输文件)有多个观察者(界面、DB工具类、守护线程),此时eventbus能提供较小的耦合度,来避免被观察者负担过重做太多的对外逻辑处理,只需要管自己的传输就行了。

五:有推送功能,收到推送后需要不同的页面或者不同的工具类来做处理的。

其他的想起来了再补充。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 4 机器学习入门——分类和最近邻

    前面学过了简单的回归和决策树,当然仅仅是使用起来简单。实际上,线性回归和决策树是很多其他算法的基础,很多高级的算法都是基于它们的组合或者变种。下面我们来看一个另...

    天涯泪小武
  • Spark——RDD操作详解

    一、基本RDD 1、针对各个元素的转化操作 最常用的转化操作是map()和filter()。转化操作map()J接收一个函数,把这个函数用于RDD中的每...

    天涯泪小武
  • Springboot集成sqlite数据库,并使用jpa、Hibernate操作sqlite

    之前举例使用jpa、Hibernate多是以mysql为例,这次因为需要使用一个内嵌式数据库,选择了sqlite,网上多是讲一些sqlite的api封装的框架。...

    天涯泪小武
  • 面试题 | 《Java面试题集》 -- 第二套

    start()用来启动一个线程,当调用start方法后,系统才会开启一个新的线程,进而调用run()方法来执行任务,而单独的调用run()就跟调用普通方法是一样...

    码神联盟
  • macOS包管理工具Homebrew

    Homebrew 是 macOS 下的包管理工具,类似于 centos 下的 yum,ubuntu下的apt 可以很方便地进行安装/卸载/更新各种软件包,bre...

    羊羽shine
  • 程序返回数据的标准格式

    通常来讲,写函数是为了重用代码,使这个函数可以通用在很多地方,比如验证表单信息,验证会员身份,验证余额,处理会员数据,查询数据

    仙士可
  • 解决stackoverflow打开慢不能注册登录

    问题原因:并不是stackoverflow被墙,而是因为stackoverflow用了google的api,而Google在天朝是用不了的,所以才导致像stac...

    王小雷
  • 国内首款智能网联无人迷你巴士在东南大学首发试运行,车内没有配置方向盘 | 热点

    镁客网
  • 2017,这四种方法帮你获知陌生网站的流量

    我在8年前写过一篇文章:如何获知陌生网站的流量?这篇文章是这个博客最大阅读量的文章之一。8年过去了,方法虽然类似,但是工具和解决方案已经有所不同。 值得对这个...

    iCDO互联网数据官
  • 郑斌:企业数据安全能力框架——数据安全能力成熟度模型的构建及应用

    摘要 安全的目的是为了保障发展,如何衡量一个拥有数据的组织的数据安全保护能力十分重要。本文探讨了这种组织所面临的数据问题及其挑战,介绍了大数据环境下数据安全发展...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券