EventBus基本用法
不准确的讲 解耦就是将问题分开处理 。就像老炮儿里的桥段一样,我无证摆摊车子应该被你收走。你打我一巴掌,这个事是另外一件事,我得打回来。言归正传。。。。 [EventBus] https://github.com/greenrobot/EventBus 这是官方的话,我就抄一句。说白了就是一个舍友做完了题,把结果发给其他众多不会做的舍友。优生就是被订阅者,其他舍友就是订阅者,扔小抄就是发布事件,小抄就是事件。 说白了就是优生的考试题答案。 根据事件类型 的意思就是英语答案扔给和你提前说好的英语不好的 那群 舍友,数学答案扔给 那个 需求数学答案的舍友,按需供给嘛。这里可以是一群 可以是一个 不强求。 就那些个不好好复习的。 会做的那个,做完了会扔出来答案的人。 在下面之前我打个比方 比如: 主线程就是 A教室 监考比较严的考场 在这里只能考试 其他线程就是 B教室 C教室。。。可以干其他的 假设你就是那个不好好复习 摸鱼的。 意思是你在A教室考试 在这里收到答案后 只能考试 不能做其他特别费时间的事情 比如 在桌子上刻字,唱歌。 意思就是你和优生默认在一个教室考试 他在A教室考你就在A 他在其他就在其他 当然在A的时候不可以干其他的 除了A你可以可以刻字或者扔粉笔头儿。 意思是优生如果在A教室考 那你就在其他教室 如果优生在B或者其他 那你就跟他一个教室 在A教室的时候收到答案只能考试 其他可以随便。。。 意思就是 不管优生在哪个教室 收答案的都被拉出来新分到一个教室 而且这个教室不是主考场 你随便干什么都行。。 1.在app的build.gradle引入 2.写一个自定义类 可以随便 3.写一个接收数据的类EventBusActivityRx 这里只布局了一个textview 用来显示和接受数据。在onCreate中注册了EventBus ,在onDestroy中取消了注册。然后点击跳转到了发射数据的类。 4.写一个数据发射类EventBusActivityTx 这里只布局了一个按钮,发送了一个数据 “发射“ ,然后回退到接受数据的类EventBusActivityRx中,在接受数据的类中看是否显示数据。 这里我们成功拿到了数据。我们这里是EventBusActivityRx 跳转到了EventBusActivityTx ,因为在EventBusActivityRx中已经注册了EventBus,所以会退回来的时候有数据。但在有些时候,我们是直接EventBusActivityTx 跳转到EventBusActivityRx中而不是回退,这时EventBusActivityRx中的EventBus还没被注册,此时接受不到数据。想要接收到数据就需要粘性事件。 我们对发射类点击事件做下修改,改为跳转到数据接收类 接受类中接收方法做下修改,将粘性事件开关打开。 我们在发射类点发射,此时接收类中EventBus还没被注册。如果不加sticky = true ,我们接收不到,加了可以接收到。这个可以自己试试。 其实就是几个接受方法中,在 同一个线程中 会根据priority的大小,接收数据,优先级高的当线程为 POSTING 时 接收到后可以通过 关闭事件的传递。这里我们直接复制 我们对数据接受类做了下修改,接受方法一个为粘性 一个非粘性,优先级一样。我们从数据接受类跳转到发射类,然后回退之后得到打印。 发现都可以接收到,我们修改优先级 得到 发现优先级高的先收到,然后我们添加取消消息继续传送 得到 发现确实在级别高的地方收到之后 消息被取消了 priority = 1的地方就没打印。也证明了优先级问题。 介绍一个和EventBus类似功能的控件 [BusUtils] https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/BusUtils.java 据说对比效率比EventBus高 大家可以试试
EventBus的使用
使用场景 :应用程序内各组件间、组件与后台线程间的通信。 比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。 EventBus的三要素 : 使用步骤 : 1. 添加依赖:implementation 'org.greenrobot:eventbus:3.0.0' 2. 注册:EventBus.getDefault().register(this); 3.构造消息发送类(post调用的对象) 4.发布消息 EventBus.getDefault().post(new Student("zyt", 19)); 5.接收消息:可以有四种线程模型选择 //接收事件 @Subscribe(threadMode = ThreadMode.MAIN) public void studentEventBus(Student student){ mShow.setText("姓名:"+student.getName()+" "+"年龄:"+student.getAge()); } 6.解注册(防止内存泄漏):EventBus.getDefault().unregister(this); 粘性事件 普通的事件我们通过post发送给EventBus,发送过后之后当前已经订阅过的方法可以收到。但是如果有些事件需要所有订阅了该事件的方法都能执行呢?例如一个Activity,要求它管理的所有Fragment都能执行某一个事件,但是当前我只初始化了3个Fragment,如果这时候通过post发送了事件,那么当前的3个Fragment当然能收到。但是这个时候又初始化了2个Fragment,那么我必须重新发送事件,这两个Fragment才能执行到订阅方法。 粘性事件就是为了解决这个问题,通过 postSticky 发送粘性事件,这个事件不会只被消费一次就消失,而是一直存在系统中,直到被 removeStickyEvent 删除掉。那么只要订阅了该粘性事件的所有方法,只要被register 的时候,就会被检测到,并且执行。订阅的方法需要添加 sticky = true 属性。 粘性事件使用步骤: 1. 添加依赖: 2.构造消息发送类(post调用的对象) 3.发送消息 4.注册(那是使用,哪里注册) 5.接收消息。跟上面使用一样,多了sticky = true 的属性。 6.解注册 一,普通事件 1.自定义事件(类似定义JavaBean,例子定义的student类),包含用户的姓名和年龄; 2.在onCreate方法中注册订阅者,在onDestroy中解注册。 3.在另一个activity中发送事件,让订阅者能够接收 二,粘性事件 1.发送粘性事件 2. 另一个activity接收注册并处理
android eventbus 底层是什么实现的
参考csdn的博客:
尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38174537
代码下载:http://download.csdn.net/detail/yuanzeyao2008/7684041
在编程过程中,当我们想通知其他组件某些事情发生时,我们通常使用观察者模式,正式因为观察者模式非常常见,所以在jdk1.5中已经帮助我们实现了观察者模式,我们只需要简单的继承一些类就可以快速使用观察者模式,在Android中也有一个类似功能的开源库EventBus,可以很方便的帮助我们实现观察者模式,那么我们就开始学习如何使用EventBus.
在接下来的内容中,我首先会介绍如何使用EventBus,然后再简单的学习一下EventBus的底层实现原理,因为仅仅学习如何使用总是感觉内心不够踏实,万一哪天出了Bug也无从下手,了解了它的基本实现后,就会用得游刃有余。好了 废话不多说,下面开始学习吧
1、下载EventBus库:
EvnetBus的下载地址:https://github.com/greenrobot/EventBus.git
2、将EventBus.jar放入自己工程的libs目录即可
3、定义一个事件,这个事件一旦被EventBus分发出去就是代表某一件事情发生了,这个事件就是某个观察者关心的事情(不需要继承任何类)
4、定义观察者,然后将该观察者注册到EventBus
5、由EventBus分发事件,告知观察者某一件事情发生了
6、使用完成后从EventBus中反注册观察者。
熟悉观察者模式的朋友肯定对于上面的流程非常熟悉,其实和观察模式基本是一样的。但是也是有区别的。在观察者模式中,所有的观察者都需要实现一个接口,这个接口有一个统一的方法如:
public void onUpdate();
然后当某一个事件发生时,某个对象会调用观察者的onUpdate方法通知观察者某件事情发生了,但是在EventBus中不需要这样,EventBus中是这样实现的:
在EventBus中的观察者通常有四种订阅函数(就是某件事情发生被调用的方法)
1、onEvent
2、onEventMainThread
3、onEventBackground
4、onEventAsync
这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:
告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下面的订阅函数实现的。
RxJava和EventBus的区别
EventBus是一个发布 / 订阅的事件总线。简单点说,就是两人约定好怎么通信,一人发布消息,另外一个约定好的人立马接收到你发的消息。
Rx:函数响应式编程 ,响应式代码的基本组成部分是Observables和Subscribers(事实上Observer才是最小的构建块,但实践中使用最多的是Subscriber,因为Subscriber才是和Observables的对应的。)。Observable发送消息,而Subscriber则用于消费消息。
主要区别是,rx里面当建立起订阅关系时,你可以用操作符做任何处理(比如转换数据,更改数据等等),而且他能处理异步的操作。 eventbus 就相当于广播,发送了,总能接收到,他在发送后是不能做任何的数据改变,如果要改变,又要重新post一次。
RxJava和EventBus的区别
二者区别如下:
1、RxJava有大量丰富强大的operator,可以满足用户的大部分数据处理需求。RxJava另一个强大的地方就是scheduler,用户可以为Observable和Subscriber指定不同的执行线程,在Android中可以方便的将Observable指定在IO线程中运行,Subscriber在UI线程中运行。
2、EventBus比较适合仅仅当做组件间的通讯工具使用,主要用来传递消息。使用EventBus可以避免搞出一大推的interface,仅仅是为了实现组件间的通讯,而不得不去实现那一推的接口。
联系:RxJava和EventBus一样也是基于观察者模式,但是使用的场景确实异步数据流的处理。
EventBus 使用详解
首先导入依赖 使用如同发布订阅,先创建事件,也就是创建任意一个类,这个就是 Event 事件,再使用如下方法发布出去,此时订阅该事件的方法则会被调用 订阅事件时,需要事先注册EventBus,一般在onStart方法中注册 别忘了还要在onStop方法取消注册 订阅事件,也就是写一个方法,参数是事先创好的类(即事件),然后用@Subscribe注解声明,当发布该事件时则调用这个方法,需要携带的数据也可以通过该类携带 四种线程模型 EventBus3.0有四种线程模型,分别是: 事件通过post发送给EventBus后,当前已经订阅过的方法当然可以收到,但是如果发送的时候还未订阅,后续再订阅也收不到这个事件。例如,一个Activity要求它管理的所有Fragment都能执行某一个事件,但是当前我只初始化了3个Fragment,如果这时候通过post发送了事件,那么当前的3个Fragment当然能收到。但是这个时候又初始化了2个Fragment,那么我必须重新发送事件,这两个Fragment才能执行到订阅方法。 粘性事件 就是为了解决这个问题,通过 postSticky 发送粘性事件,这个事件不会只被消费一次就消失,而是一直存在系统中,直到被 removeStickyEvent 删除掉,那么只要订阅了该粘性事件即可收到并执行。 接收粘性事件除了用@Subscribe注解声明,还需要添加 sticky = true 属性 总结:主要是在常规通信方式写起来很复杂或需要解耦的情况下使用EventBus