EventBus的使用
2015-09-28 18:19
232 查看
EventBus用了好久了,一直没有整理一下。
我们往简单里说,EventBus的出现,让我们在大部分情况下,不需要使用broadcast来在不同的activity,fragment,甚至是adapter(我知道你们经常纠结adapter和activity的交互!)之间交互了。
当然,如果你要获取系统广播什么的,还是需要broadcast的。
而且EventBus的回调很丰富,你甚至可以指定你的回调运行在哪个线程里(这个很方便有木有)
我们举一个例子来说明一下:
废代码我们就不写了,省得大家看起来乱。
我们来举一个从adapter到activity传值的例子。
首先我们有一个adapter,叫ListAdapter,我们打算在点击ListAdapter中某个item的按钮时,发送一个消息到MainActivity,MainActivity接收一个消息后,弹出一个toast提示框。
跟动态广播一样,首先我们要为每一个广播指定类型,所以我们写了一个Event类:
以及定义了几种事件:
定义完了后,首先我们要在MainActivity的onCreate方法中注册一个EventBus:
并在onDestroy方法中反注册它:
这样,MainActivity就可以接收到EventBus的消息了。
然后我们要在ListAdapter里面发送消息:
梳理一下,现在我们完成了消息发送和消息接收方的注册了。那对比广播,我们还需要一个接受消息的地方。
其实很简单,我们回到MainActivity,写一个方法:
然后这个方法会自动接收MainActivity收到的消息。
是不是很奇怪,为什么我随便定义了一个方法,既没有指定这个方法接收消息,而且这个方法也不是我重写的?(比如继承了EventBus类,然后重写它的接收方法)
最初我也很奇怪,所以我做了一个实验,我把onEventMainThread改名了,改成offEventMainThread,结果居然运行报错,大致意思是说,我在MainActivity中注册了EventBus,但是我没有指定接收方法!
又找了些资料研究了下,EventBus应该是注册了之后,就会在这个类MainActivity装载的时候,自动扫描是否有接收方法,如果没有就直接抛出异常。
除了onEventMainThread,EventBus还有别的接收方法,我直接饮用了别的资料:
EventBus还有另外有个不同的函数,他们分别是:
1、onEvent
2、onEventMainThread
3、onEventBackgroundThread
4、onEventAsync
这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:
告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下面的订阅函数实现的。
onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.
我们往简单里说,EventBus的出现,让我们在大部分情况下,不需要使用broadcast来在不同的activity,fragment,甚至是adapter(我知道你们经常纠结adapter和activity的交互!)之间交互了。
当然,如果你要获取系统广播什么的,还是需要broadcast的。
而且EventBus的回调很丰富,你甚至可以指定你的回调运行在哪个线程里(这个很方便有木有)
我们举一个例子来说明一下:
废代码我们就不写了,省得大家看起来乱。
我们来举一个从adapter到activity传值的例子。
首先我们有一个adapter,叫ListAdapter,我们打算在点击ListAdapter中某个item的按钮时,发送一个消息到MainActivity,MainActivity接收一个消息后,弹出一个toast提示框。
跟动态广播一样,首先我们要为每一个广播指定类型,所以我们写了一个Event类:
public class Event<T> { private EventType eventType; private T message; public Event(EventType eventType) { this.eventType = eventType; } public Event(EventType eventType, T message) { this.eventType = eventType; this.message = message; } public EventType getEventType() { return eventType; } public void setEventType(EventType eventType) { this.eventType = eventType; } public T getMessage() { return message; } public void setMessage(T message) { this.message = message; } }
以及定义了几种事件:
public enum EventType { START_MINING, ENTER_GAME_TAB, }
定义完了后,首先我们要在MainActivity的onCreate方法中注册一个EventBus:
EventBus.getDefault().register(this);
并在onDestroy方法中反注册它:
EventBus.getDefault().unregister(this);
这样,MainActivity就可以接收到EventBus的消息了。
然后我们要在ListAdapter里面发送消息:
holder.image_start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //这里,我们在按钮的点击事件里发送消息 EventBus.getDefault().post( new Event(EventType.START_MINING, getItem(pos).mountainLevel)); } });
梳理一下,现在我们完成了消息发送和消息接收方的注册了。那对比广播,我们还需要一个接受消息的地方。
其实很简单,我们回到MainActivity,写一个方法:
public void onEventMainThread(Event event) { String msg = "onEventMainThread收到了消息:" + event.getMessage(); Toast.makeText(mContext, msg, Toast.LENGTH_LONG).show(); }
然后这个方法会自动接收MainActivity收到的消息。
是不是很奇怪,为什么我随便定义了一个方法,既没有指定这个方法接收消息,而且这个方法也不是我重写的?(比如继承了EventBus类,然后重写它的接收方法)
最初我也很奇怪,所以我做了一个实验,我把onEventMainThread改名了,改成offEventMainThread,结果居然运行报错,大致意思是说,我在MainActivity中注册了EventBus,但是我没有指定接收方法!
又找了些资料研究了下,EventBus应该是注册了之后,就会在这个类MainActivity装载的时候,自动扫描是否有接收方法,如果没有就直接抛出异常。
除了onEventMainThread,EventBus还有别的接收方法,我直接饮用了别的资料:
EventBus还有另外有个不同的函数,他们分别是:
1、onEvent
2、onEventMainThread
3、onEventBackgroundThread
4、onEventAsync
这四种订阅函数都是使用onEvent开头的,它们的功能稍有不同,在介绍不同之前先介绍两个概念:
告知观察者事件发生时通过EventBus.post函数实现,这个过程叫做事件的发布,观察者被告知事件发生叫做事件的接收,是通过下面的订阅函数实现的。
onEvent:如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
onEventMainThread:如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
onEventBackground:如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
onEventAsync:使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.
相关文章推荐
- zoj 5518 异或
- 多线程的五种常见死锁问题 (看看你能答对几个)
- 部署巡检脚本
- iOS9 URL Schema 白名单 微信
- 黑马程序员——Java基础语法(一)_关键字、标识符、常量、变量、运算符
- java 深拷贝
- 剖析Java中线程编程的概念
- leetcode:Single Number
- 网络图片加载
- 题解(中秋专场)
- python web开发框架django安装和测试
- HDU 5481:Desiderium(线段树)
- 关于attr的用法,自己写的一个例子。
- 如何把百度地图应用到安卓中
- 关于启动Aptana studio弹出failed to load the jni shared library
- SQL Server 2005数据库日志丢失的恢复
- 手机防盗2
- Java垃圾回收机制
- scala VS python2 (linux or shell)
- Linux_屏蔽360、scanv、QQ管家等IP扫描