源码解析-post
来源:互联网 发布:琉璃神社新的域名 编辑:程序博客网 时间:2024/06/07 20:33
1、应用方调用如下:
EventMsg msg = new EventMsg();msg.setMsg("hello eventBus");EventBus.getDefault().post(msg);
2、post()
public void post(Object event) { // PostingThreadState保存着事件队列和线程状态信息 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; } }}
在PostingThreadState中保存了事件队列,以及线程的一些状态信息。首先从PostingThreadState对象中取出事件队列,然后再将当前的事件插入到事件队列当中。最后将队列中的事件依次交由postSingleEvent方法进行处理,并移除该事件。下面就在进入postSingleEvent方法中看一下。
2.1 postSingleEvent
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { Class<?> eventClass = event.getClass(); boolean subscriptionFound = false; if (eventInheritance) { // 获取所有事件并存放在List中,这里表示事件存在继承关系,向上查找事件的父类 List<Class<?>> eventTypes = lookupAllEventTypes(eventClass); // 处理事件 int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } // 找不到该事件时的异常处理 if (!subscriptionFound) { if (logNoSubscriberMessages) { Log.d(TAG, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } }}
对于eventInheritance表示是否向上查找事件的父类。它的默认值为true,可以通过在EventBusBuilder中来进行配置。当eventInheritance为true时,则通过lookupAllEventTypes找到所有的父类事件并存发在List中,然后通过postSingleEventForEventType方法对事件逐一处理。
2.2 postSingleEventForEventType
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { // 同步取出该事件对应的Subscription集合 CopyOnWriteArrayList<Subscription> subscriptions; synchronized (this) { subscriptions = subscriptionsByEventType.get(eventClass); } if (subscriptions != null && !subscriptions.isEmpty()) { for (Subscription subscription : subscriptions) { postingState.event = event; postingState.subscription = subscription; boolean aborted = false; try { // 对事件进行处理 postToSubscription(subscription, event, postingState.isMainThread); aborted = postingState.canceled; } finally { postingState.event = null; postingState.subscription = null; postingState.canceled = false; } if (aborted) { break; } } return true; } return false;}
还记得在订阅者进行注册时候,以订阅事件作为Key,将Subscription的List集合作为Value保存到了一个Map集合当中。而就在这个方法中通过事件类型取出Subscription的List集合,然后调用了postToSubscription方法来处理事件并执行订阅方法。下面再来看一下postToSubscription方法。
2.3 postToSubscription
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.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); }}void invokeSubscriber(Subscription subscription, Object event) { try { subscription.subscriberMethod.method.invoke(subscription.subscriber, event); } catch (InvocationTargetException e) { handleSubscriberException(subscription, event, e.getCause()); } catch (IllegalAccessException e) { throw new IllegalStateException("Unexpected exception", e); }}
这一路对订阅事件的分发,总算差不多要到头了。在这里取出订阅方法的线程模式,之后根据订阅方法所设置的线程模式来选择线程来执行订阅方法的线程。
订阅方法的线程模式为MAIN的时候。提交事件的线程是主线程则直接执行invokeSubscriber方法。否则加入到mainThreadPoster对象的队列中,而mainThreadPoster对象他是HandlerPoster对象。HandlerPoster继承自Handler,也即是通过Handler将订阅方法切换到主线程执行。
- 源码解析-post
- Jfinal HttpKit.post(url,data)源码解析
- post解析
- post解析
- Android Volley源码 解析(一)之GET、POST请求篇
- WebRequest post读取源码
- WSGI.解析POST请求
- post参数解析
- 网络请求 - Post解析
- HttpURLConnection post解析
- WSGI: 解析POST请求
- 解析HttpUtil--post方法
- XlistView(POST解析、吐司)
- 源码解析
- 源码解析
- php post数据,解析post数据
- http post 文件上传解析
- 接收POST数据,解析XML
- getParameter和getAttribute的区别
- viewPager搭载指示器,轻松上手
- myrocks proc init梳理
- CDN技术详解
- 25、Selenium + Python 实现 UI 自动化测试-unknown error: Element is not clickable at point (x,y)
- 源码解析-post
- 面试时关于“工作可预见困难有哪些”应聘者如何巧妙回答
- android读写excel文件
- 论文阅读《Long-term Temporal Convolutions for Action Recognition》
- python读取外部数据之读取csv格式
- 自动账户确定之AUM
- 图的数据结构
- reorder-list Java code
- continue;go to;;break;return