EventBus3.0使用详解
来源:互联网 发布:幼儿看图学英语软件 编辑:程序博客网 时间:2024/05/19 13:16
转至:http://blog.csdn.net/baidu_17508977/article/details/51612098
前言:
EventBus是最近接手的一个项目上在用的开源库,但是我这个EventBus菜鸟,之前还没用过,还没好好感受过它的好处,前几天刚刚看完源码,对EventBus有了一个大体的了解,看完源码之后,感觉此库真是好处多多啊,不吹不黑,不服来辩,哈哈哈,不吹了,根据官方doc,记录一下EventBus的使用。
优势:
使用一个开源库,我们总要知道他的优势所在,要不然那么多开源库,为毛非要用这个,你说是这个理不。那我们就看一下他的优势所在,
想知道官方的介绍的可以去这里查看:EventBus官方介绍
EventBus是安卓发布/订阅事件总线的优化
翻译过来其实也就这么核心几条:
1. 简化组件间的通信
(1).对发送和接受事件解耦
(2).可以在Activity,Fragment,和后台线程间执行
(3).避免了复杂的和容易出错的依赖和生命周期问题
2. 让你的代码更简洁
3. 更快
4. 更轻量(jar包小于50K)
5. 实践证明已经有一亿多的APP中集成了EventBus
6. 拥有先进的功能比如线程分发,用户优先级等等
基本结构:
盗图一张:
基本用法:
1. 添加gradle依赖compile 'org.greenrobot:eventbus:3.0.0'
Step 1: Define events
Events 就是一个普通的JavaBean,没有任何特殊要求,例如:
public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = message; }}
Step 2: Prepare subscribers
准备subcriber的回调method,来处理post event,从EventBus_3开始,用注解@Subscribe来定义subscriber的回调method,方法名可以任意定义
例如:
// This method will be called when a MessageEvent is posted @Subscribe public void onMessageEvent(MessageEvent event){ Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show(); } // This method will be called when a SomeOtherEvent is posted @Subscribe public void handleSomethingElse(SomeOtherEvent event){ doSomethingWith(event); }
Subscribers与BroadcastReceiver类似,需要register和unregister,只有注册了EventBus,回调方法才起作用,在Android中,一般与Activity的生命周期绑定在一起
官方demo:
@Overridepublic void onStart() { super.onStart(); EventBus.getDefault().register(this);}@Overridepublic void onStop() { EventBus.getDefault().unregister(this); super.onStop();}
Step 3: Post events
前面准备好,这里就可以任意post event。所有已注册EventBus的subscriber只要event_type相匹配,都可以收到该event
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
ThreadMode用法:
当牵扯到线程间通讯时,特别是,主线程,后台线程,耗时操作线程,等线程间的通讯时,我们就必须倍加小心,好在EventBus很强大,已经考虑到了,我们只需要根据具体的需求去配置,不同的线程模式ThreadMode即可:
ThreadMode源码:
public enum ThreadMode { POSTING, MAIN, BACKGROUND, ASYNC;}
接着,逐一分析下,各个模式适合的场景:
POSTING
这个模式最简单,也是EventBus默认的模式,也就是说:post event和handle event在同一个线程@Subscribe(threadMode = ThreadMode.POSTING) // ThreadMode is optional here//默认为Posting,可以不指定public void onMessage(MessageEvent event) { log(event.message);}
MAIN
当指定threadMode=Main时,此时,handle event是运行在UI线程的,如果,post event也是在UI线程,就跟Posting模式一样,Warning:使用此模式,不能堵塞UI线程// Called in Android UI's main thread@Subscribe(threadMode = ThreadMode.MAIN)public void onMessage(MessageEvent event) { textField.setText(event.message);}
BACKGROUND
当指定threadMode=Background时,如果 post event不在UI线程,那么handle event 会在此线程回调;如果 post event在UI线程,EventBus使用一个后台线程,按顺序分发所有事件。Warning:使用此模式,不能堵塞后台线程// Called in the background thread@Subscribe(threadMode = ThreadMode.BACKGROUND)public void onMessage(MessageEvent event){ saveToDisk(event.message);}
ASYNC
当指定threadMode=Async时,handle event始终独立于UI线程和post event所在的线程,即:和post event 不在同一线程,也不在UI线程。此模式适合耗时任务:e.g.:网络链接。Warning:避免触发大量的长时间运行的异步线程,来限制并发线程的数量。EventBus使用Thread pool高效 的使用线程// Called in a separate thread@Subscribe(threadMode = ThreadMode.ASYNC)public void onMessage(MessageEvent event){ backend.send(event.message);}
Configuration用法:
当默认的EventBus不足以满足需求时,EventBusBuilder就上场了,EventBusBuilder允许配置各种需求的EventBus
例如1:当没有subscribers的时候,eventbus保持静默:EventBus eventBus = EventBus.builder().logNoSubscriberMessages(false) .sendNoSubscriberEvent(false).build();例如2:配置异常:默认情况下:eventbus捕获onevent抛出的异常,并且发送一个SubscriberExceptionEvent 可能不必处理EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();
配置默认的eventbus单例
官方推荐:在application类中,配置eventbus单例,保证eventbus的统一
例如:配置eventbus 只在DEBUG模式下,抛出异常,便于自测,同时又不会导致release环境的app崩溃EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();
Sticky Events用法:
前面说的一般的post event,正常流程,必须是先register,然后post event,handle event才能起作用。但是当我们post event时,还没有subcriber怎么办?但是又想后注册的subscriber,能收到消息,这时sticky event就开始大显身手了。
Warning:EventBus会把最后一个sticky event记录在内存中,然后分发给subscriber
来看下官方的Demo
1 post sticky event:EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));2 启动一个新的Activity,准备subscriber,注册后,所有的sticky subscriber的回调方法,会马上获得之前的sticky event@Overridepublic void onStart() { super.onStart(); EventBus.getDefault().register(this);}//注意这里sticky=true@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)public void onEvent(MessageEvent event) { // UI updates must run on MainThread textField.setText(event.message);}@Overridepublic void onStop() { EventBus.getDefault().unregister(this); super.onStop();}
Getting and Removing sticky Events manually
如上所述,当subscriber注册后,最后一个sticky event会自动匹配。但是,有些时候,主动去检查sticky event会更方便,并且 sticky event 需要remove,阻断继续传递。
官方demo
//返回的是之前的sticky eventMessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);// Better check that an event was actually posted beforeif(stickyEvent != null) { // Now do something with it}
2中sticky event使用方法都可行,看业务需要和个人习惯,选择合适的使用方法
Priorities and Event Cancellation用法:
大多数情况下,eventbus不需要改变线程优先级,或者取消event,但是不排除少数情况,需要改变线程优先级。
Subscriber Priorities
官方demo
//priority默认为0,不同ThreadMode下的分发流程不受优先级的影响//优先级高的可以优先获得消息@Subscribe(priority = 1);public void onEvent(MessageEvent event) {…}
Cancelling event delivery
如果,不希望后续的subcriber收到消息,可以在收到消息后,调用cancelEventDelivery(Object event) 取消消息的后续传递。
官方demo
@Subscribepublic void onEvent(MessageEvent event){// Process the event…EventBus.getDefault().cancelEventDelivery(event) ;}
Note:一般情况下,event的取消发生在高优先级的subscriber
ProGuard 混淆规则
-keepattributes *Annotation*-keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe <methods>;}-keep enum org.greenrobot.eventbus.ThreadMode { *; }# Only required if you use AsyncExecutor-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable);}
AsyncExecutor
关于AsyncExecutor的用法,还是看官方文档吧,因为这个我也没用过
Subscriber Index
这是eventbus3.0新增的功能,是对原有功能的优化,为register提供了一种比反射更快速的方案,也就是对应源码中的private List findUsingInfo(Class
小结
看完官方文档介绍,对eventbus的使用基本上就没什么问题了,再加上看了3天的源码解析,对eventbus的内部结构总算是有了一个大概的了解,如果有不对的地方,欢迎指正,另外对eventbus源码解析有高见的,也欢迎留言交流
EventBus源码解析推荐2篇我认为比较好的,也可以帮助阅读源码
- . EventBus源码解析
- . EventBus3.0源码解析
- . EventBus官方Doc
- . EventBus3.0API
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0的使用详解
- 【Android】- EventBus3.0使用详解
- EventBus3.0最新使用文档详解
- EventBus3.0 使用详解(一)
- EventBus3.0详解
- EventBus3.0详解
- EventBus3.0使用总结
- EventBus3.0使用总结
- EventBus3.0使用
- 01-数据库的基本介绍
- citusdb性能测试
- 2017.6.20
- Python学习之旅-18
- bzoj 2339: [HNOI2011]卡农 组合数学+递推
- EventBus3.0使用详解
- BZOJ 1316: 树上的询问 点分治
- Java开发课2017.06.20上课笔记
- jquery怎样限制上传图片的大小和像素宽高,分辨率
- 004-识别机会窗口|借势破局
- structured streaming ——wordcounts_kafka
- ThinkPHP实现支付宝接口功能
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalab
- 讲讲我在Linux上安装和配置MXNet的经历