EventBus 3.0源码学习(二)
来源:互联网 发布:氮氧化物历年排放数据 编辑:程序博客网 时间:2024/06/08 06:40
一、post和postSticky的区别
/** Posts the given event to the event bus. */ public void post(Object event) { PostingThreadState postingState = currentPostingThreadState.get(); List<Object> eventQueue = postingState.eventQueue; eventQueue.add(event); if (!postingState.isPosting) { postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper(); postingState.isPosting = true; if (postingState.canceled) { throw new EventBusException("Internal error. Abort state was not reset"); } try { while (!eventQueue.isEmpty()) { postSingleEvent(eventQueue.remove(0), postingState); } } finally { postingState.isPosting = false; postingState.isMainThread = false; } } }
public void postSticky(Object event) { synchronized (stickyEvents) { stickyEvents.put(event.getClass(), event); } // Should be posted after it is putted, in case the subscriber wants to remove immediately post(event); }
从上面的比较来看postSticky利用 Map<Class<?>, Object> 数据结构来存储sticky事件,再调用post方法。接下去就是等待时机触发了,这个时机就是等待注册的那个时候,然后标有sticky标记的方法就好被触发执行。在EventBus类中有一个subscribe方法里面有如下的一段代码,这段主要是判断是否是黏性事件,如果是的话就执行,不是的话直接跳过。
if (subscriberMethod.sticky) { if (eventInheritance) { // Existing sticky events of all subclasses of eventType have to be considered. // Note: Iterating over all events may be inefficient with lots of sticky events, // thus data structure should be changed to allow a more efficient lookup // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>). Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry<Class<?>, Object> entry : entries) { Class<?> candidateEventType = entry.getKey(); if (eventType.isAssignableFrom(candidateEventType)) { Object stickyEvent = entry.getValue(); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } } } else { Object stickyEvent = stickyEvents.get(eventType); checkPostStickyEventToSubscription(newSubscription, stickyEvent); } }
其实post和postSticky的区别用通俗的话来讲就是post要先注册,然后立刻开始处理事件对象。而postSticky就是不管你有没有注册,先发送事件对象再说,然后存储起来,直到有对象来注册这个sticky事件。
二、其它类分析
订阅方法类:主要用来存储订阅方法的相关信息。
//有方法、线程模型、事件类型、优先级、粘性等属性。public class SubscriberMethod { final Method method; final ThreadMode threadMode; final Class<?> eventType; final int priority; final boolean sticky; /** Used for efficient comparison */ String methodString;}
订阅者信息类,用来存储订阅者和订阅方法。
final class Subscription { final Object subscriber; final SubscriberMethod subscriberMethod; /** * Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery * {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions. */ volatile boolean active;}
EventBus的事件处理函数通常需要指定处理线程,EventBus提供了四种线程模型POSTING(默认)、MAIN、BACKGROUND、ASYNC
public enum ThreadMode { //POSTING表示如果使用事件处理函数指定了线程模型为PostThread,那么该事件在哪个线程发布出来的,事件处理函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程。在线程模型为PostThread的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR。 POSTING,//如果使用事件处理函数指定了线程模型为MainThread,那么不论事件是在哪个线程中发布出来的,该事件处理函数都会在UI线程中执行。该方法可以用来更新UI,但是不能处理耗时操作。 MAIN,//如果使用事件处理函数指定了线程模型为BackgroundThread,那么如果事件是在UI线程中发布出来的,那么该事件处理函数就会在新的线程中运行,如果事件本来就是子线程中发布出来的,那么该事件处理函数直接在发布事件的线程中执行。在此事件处理函数中禁止进行UI更新操作 BACKGROUND, //如果使用事件处理函数指定了线程模型为Async,那么无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行。同样,此事件处理函数中禁止进行UI更新操作 ASYNC}
阅读全文
0 0
- EventBus 3.0源码学习(二)
- EventBus (二) 源码分析
- EventBus源码解析(二)
- android EventBus 学习(二)
- EventBus(二)之源码分析
- EventBus源码详解(二):进阶使用
- EventBus源码解析二
- EventBus 源码试读(二)
- EventBus源码学习
- EventBus源码学习笔记
- EventBus源码分析(二):编译库源码解析
- EventBus学习笔记二
- Guava EventBus源码分析(二):注册订阅者方法
- Android EventBus框架(二)之源码简单解析
- Android EventBus源码解析 带你深入理解EventBus(二)
- EventBus 3.0 源码分析
- EventBus 3.0源码解析
- EventBus 3.0 源码分析
- Java集合简单介绍
- java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射
- [bigdata-107] node.js的安装并实现一个运营商报告的提交功能
- 全球MCU市场和技术发展趋势
- 基于JAVA代码 获取手机基本信息(本机号码,SDK版本,系统版本,手机型号)
- EventBus 3.0源码学习(二)
- Wireshark抓包iOS入门教程
- 如何加快Gradle的构建速度
- opencv 最小二乘拟合平面
- Android关于 'roundIcon' in package '的错误
- =搬家=
- Faster R-CNN学习笔记
- 29 《斐多》 -豆瓣评分9.0
- 深度学习视觉领域常用数据集汇总