EventBus3.0——基本使用
来源:互联网 发布:淘宝客服月总结怎么写 编辑:程序博客网 时间:2024/06/05 16:50
EventBus3.0——基本使用
EventBus在线程间通信有着明显的优势,普及度也非常的高,特别是升级到3.0后,使用起来更加方便、简洁,性能也得到了很好优化,并且加入了注解,其使用方式相对以前有了很大的变动,今天我就带大家来学习一下EventBus3.0的基本使用。这里针对的是以前有使用过EventBus的朋友,框架原理就不过多解释了,只贴重要部分源码。基本概念不多说,我这里以fragment之间通信为例,先上效果图:
左边为fragment1、右边为fragment2,使用方法如下:
第一步、注册观察者(订阅者):
1、注册(唯一注册方法)
@Override public void onCreate(@Nullable Bundle savedInstanceState) { EventBus.getDefault().register(this); super.onCreate(savedInstanceState); }
2、解除注册
@Override public void onDestroyView() { EventBus.getDefault().unregister(this); super.onDestroyView(); }
注:EventBus.getDefault()的作用是为了获取单例默认实例,register的作用是为了通过反射或者索引方式获取当前类中的注解方法,并存到Map集合中,以便post的时候使用,unregister则是释放Map集合中的缓存。
第二步、创建观察者(订阅者):
一共有四种创建观察者的方法(3.0以前版本,方法名必须如下):
onEvent:发布事件和接收事件在同一线程,不能做耗时操作,容易导致事件分发延迟。onEventMainThread:不论事件在哪个线程中发布,接收事件只在UI线程中执行,也是最常用的订阅函数,不能做耗时操作。onEventBackground:不论事件在哪个线程中发布,接收事件只在子线程中执行,如果事件是在子线程中发布,则接收事件直接在该子线程中执行。onEventAsync:无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync。
相信用过EventBus的朋友对这四种观察者方法都非常熟悉,但遗憾了是到了3.0的版本他们就退休了,因为引进了注解@Subscribe,我们通过源码来看一下,这个注解是怎么定义的:
public @interface Subscribe { ThreadMode threadMode() default ThreadMode.POSTING; /** * If true, delivers the most recent sticky event (posted with * {@link EventBus#postSticky(Object)}) to this subscriber (if event available). */ boolean sticky() default false; /** Subscriber priority to influence the order of event delivery. * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of * delivery among subscribers with different {@link ThreadMode}s! */ int priority() default 0;}一共有三个成员变量:threadMode——线程模式(默认为ThreadMode.POSTING),sticky()——是否具备粘性,priority——优先级,相信这几个变量大家不陌生吧,3.0以前的注册函数传参是不是也有类似的参数,而且有了注解,我们在创建观察者的时候方法名也没有限制了。
那么3.0如何创建观察者呢,3.0版本通过注解描述观察者的信息,更加清晰直观的看到每个方法的线程模式、是否接受粘性消息、优先级,创建方式如下:
@Subscribe(threadMode = ThreadMode.POSTING,priority = 1) public void pdmEvent(Student student) { if (student != null) tvContent.setText("onEvent " +student.getContent()); Log.e(TAG,"onEvent: " + Thread.currentThread().getName()); } @Subscribe(threadMode = ThreadMode.MAIN,priority = 2,sticky = true) public void pdmEventMainThread(Student student) { if (student != null) tvContent1.setText( "onEventMainThread " + student.getContent()); Log.e(TAG,"onEventMainThread: " + student.getContent()); } @Subscribe(threadMode = ThreadMode.BACKGROUND,priority = 3) public void pdmEventBackground(Student student) { Log.e(TAG,"onEventBackground: " + Thread.currentThread().getName()); } @Subscribe(threadMode = ThreadMode.ASYNC,priority = 4) public void pdmEventAsync(Student student) { Log.e(TAG,"onEventAsync: " + Thread.currentThread().getName()); }这里源码是通过获取方法的注解来判断哪些函数是EventBus所需要的观察者方法,通过注解变量threadMode的值判断观察者的线程模式,不再需要根据方法名来判断了。源码用一个枚举来定义ThreadMode,跟原来的四种观察者函数一一对应,这样我们就不需要死死的记着那几个函数名了:
public enum ThreadMode { POSTING, MAIN, BACKGROUND, ASYNC}我们来看一下源码是怎么通过注解Subscribe中的属性值来决定观察者执行的线程:
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) {//注解Subscribe的ThreadMode属性 case POSTING://当前线程 invokeSubscriber(subscription, event); break; case MAIN://主线程 if (isMainThread) { invokeSubscriber(subscription, event); } else { mainThreadPoster.enqueue(subscription, event); } break; case BACKGROUND://子线程 if (isMainThread) { backgroundPoster.enqueue(subscription, event); } else { invokeSubscriber(subscription, event); } break; case ASYNC://新开子线程 asyncPoster.enqueue(subscription, event); break; default: throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode); } }第三步、发布事件(fragment2):
@Override public void onListItemClick(ListView listView, View view, final int position, long id) {// new Thread(new Runnable() {// @Override// public void run() { EventBus.getDefault().post(getListView().getItemAtPosition(position)); Log.e(TAG, "run: " + Thread.currentThread().getName());// }// }).start(); super.onListItemClick(listView, view, position, id); }到了这里,EventBus的基本使用就讲完,最后我们来验证下threadMode中的四个枚举值的设置,是不是跟以前版本的四种观察者方法能够一一对应,下面看日志打印信息:明显符合,其他都没有异议,一个萝卜一个坑,但是threadMode = ThreadMode.PSTING是否跟发布事件所在线程一样,对应以前版本的onEvent方法,还有待确定,这里只能看出它在主线程运行,那么我们再将发布事件放到子线程中,来做进一步验证:@Override public void onListItemClick(ListView listView, View view, final int position, long id) { new Thread(new Runnable() { @Override public void run() { EventBus.getDefault().post(getListView().getItemAtPosition(position)); Log.e(TAG, "run: " + Thread.currentThread().getName()); } }).start(); super.onListItemClick(listView, view, position, id); }默认模式的观察者也要记得修改,因为它所在线程跟发布事件线程是一样的,记得注释掉UI操作部分:再看打印日志:@Subscribe(threadMode = ThreadMode.POSTING,priority = 1) public void pdmEvent(Student student) {// if (student != null)// tvContent.setText("onEvent " +student.getContent()); Log.e(TAG,"onEvent: " + Thread.currentThread().getName()); }发布事件的当前线程是Thread-146,threadMode = ThreadMode.PSTING所在方法线程也是Thread-146,到了这里最后一点疑虑也解决了,ThreadMode四个枚举值分别对应了以前版本的四种观察者方法。下一章我会就EventBus注解(@Subscribe)中stick和priority的使用做讲解。(有时间也会专门针对3.0的源码做一下阐述)
最后给没用过EventBus的朋友提供一个小demo参考:http://download.csdn.net/detail/aiyh0202/9662495
1 0
- EventBus3.0——基本使用
- EventBus3.0——索引的使用
- EventBus3.0事件总线的基本使用
- Android——EventBus3.0的使用详解
- Android事件总线之EventBus3.0基本使用
- EventBus3.0使用总结
- EventBus3.0使用总结
- EventBus3.0使用详解
- EventBus3.0使用
- EventBus3.0的使用
- EventBus3.0使用
- EventBus3.0使用详解
- EventBus3.0使用详解
- EventBus3.0使用
- EventBus3.0使用详解
- EventBus3.0使用介绍
- EventBus3.0的使用
- EventBus3.0的使用
- Eclipse 安装最新SVN插件
- Android中子线程真的不能更新UI吗?
- centos6.6 升级mysql到5.5 ,因为默认是5.1
- 第八周 OJ总结<1>-求倒数和【简单循环】
- ubuntu环境下使用G++编译C++
- EventBus3.0——基本使用
- 关闭 mysql 错误 SQL Error: 1366: Incorrect string value: "\xE8\xAF\xA6\xE7\xBB\x86…" for column "addres
- /lib64/gcc_s.so.1: file too short解决方案
- 这一刻,我决定换一种活法
- Java ExecutorService四种线程池的例子与说明
- STM32内存与堆栈
- 数独游戏--画表格
- Xcode8遇到的一些问题
- Unity Shader 学习