【第五篇】androidEventbus源代码阅读和分析之发送粘性事件和接收粘性事件代码分析
2015-07-27 14:06
627 查看
代码里面发送粘性事件代码如下:
// 发送Sticky事件 EventBus.getDefault().postSticky(new User("soyoungboy", "西安财经学院"), "soyoungboy");然后我们进入postSticky方法里面去:EventType 是什么?该类是描述一个函数唯一性的对象,参数类型、tag两个条件保证了对象的唯一性.通过该类的对象来查找注册了相应类型和tag的所有订阅者{@see* Subscription}, 并且在接到消息时调用所有订阅者对应的函数.mStickyEvents是什么?
private List<EventType> mStickyEvents = Collections.synchronizedList(new LinkedList<EventType>());是个list集合,用于存储eventType的list集合。
/*** 发布Sticky事件,tag为EventType.DEFAULT_TAG** @param event*/public void postSticky(Object event) {postSticky(event, EventType.DEFAULT_TAG);}/*** 发布含有tag的Sticky事件** @param event 事件* @param tag 事件tag*/public void postSticky(Object event, String tag) {EventType eventType = new EventType(event.getClass(), tag);eventType.event = event;mStickyEvents.add(eventType);// 处理sticky事件// mDispatcher.handleStickyEvent(eventType, null);}这是发布,如何接收粘性事件,我们也看下源码来分析下:首先要注册粘性事件的eventbus:
EventBus.getDefault().registerSticky(this);走进registerSticky代码里面看下:
/*** 以sticky的形式注册,则会在注册成功之后迭代所有的sticky事件** @param subscriber*/public void registerSticky(Object subscriber) {this.register(subscriber);// 处理sticky事件mDispatcher.dispatchStickyEvents(subscriber);}register代码不进行分析,因为前面讲过,就是将@ subscriber的订阅者对象放入map集合里面去重点分析下 mDispatcher.dispatchStickyEvents(subscriber);
void dispatchStickyEvents(Object subscriber) {for (EventType eventType : mStickyEvents) {handleStickyEvent(eventType, subscriber);}}在往下面走:根据不同的ThreadMode去调用不同的handler(这里是事件分发器对象)的handleEvent方法。ThreadMode是在代码里面通过注解传进来的。
/*** 处理单个Sticky事件** @param eventType* @param aEvent*/private void handleStickyEvent(EventType eventType, Object subscriber) {//从缓存获取eventTypes内容List<EventType> eventTypes = getMatchedEventTypes(eventType, eventType.event);// 事件Object event = eventType.event;//循环遍历eventType集合for (EventType foundEventType : eventTypes) {Log.e("", "### 找到的类型 : " + foundEventType.paramClass.getSimpleName()+ ", event class : " + event.getClass().getSimpleName());//从订阅者的map集合里面获取指定的订阅者集合的list集合,根据eventTypefinal List<Subscription> subscriptions = mSubcriberMap.get(foundEventType);if (subscriptions == null) {continue;}//遍历list集合for (Subscription subItem : subscriptions) {final ThreadMode mode = subItem.threadMode;EventHandler eventHandler = getEventHandler(mode);// 如果订阅者为空,那么该sticky事件分发给所有订阅者.否则只分发给该订阅者if (isTarget(subItem, subscriber)&& (subItem.eventType.equals(foundEventType)|| subItem.eventType.paramClass.isAssignableFrom(foundEventType.paramClass))) {// 处理事件eventHandler.handleEvent(subItem, event);}}}}mDispatcher是个事件分发器;EventDispatcher事件分发器中有三条个ThreadEventHandler:UIThreadEventHandlerDefaultEventHandlerAsyncEventHandler都实现了EventHandler事件处理接口,实现handleEvent方法:UIThreadEventHandler中实现:事件处理在UI线程,通过Handler将事件处理post到UI线程的消息队列,UIThreadEventHandler的handleEvent指向DefaultEventHandler的handleEvent方法;列
/*** @param subscription* @param event*/public void handleEvent(final Subscription subscription, final Object event) {mUIHandler.post(new Runnable() {@Overridepublic void run() {mEventHandler.handleEvent(subscription, event);}});}AsyncEventHandler中实现:默认也是子类为DefaultEventHandler的handleEvent去实现,重点还是DefaultEventHandler中的handleEvent的实现。
/*** 将订阅的函数执行在异步线程中** @param subscription* @param event*/public void handleEvent(final Subscription subscription, final Object event) {mDispatcherThread.post(new Runnable() {@Overridepublic void run() {mEventHandler.handleEvent(subscription, event);}});}DefaultEventHandler中实现:重点是subscription.targetMethod.invoke(subscription.subscriber.get(), event),代码走到最后走到这里,那么到这这里执行了什么操作呢;执行反射操作,根据参数查找方法,进行反射调用。
/*** handle the event** @param subscription* @param event*/public void handleEvent(Subscription subscription, Object event) {if (subscription == null|| subscription.subscriber.get() == null) {return;}try {// 执行subscription.targetMethod.invoke(subscription.subscriber.get(), event);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
相关文章推荐
- android底部弹出菜单
- android listView点击item,高亮显示
- Android完全退出程序
- android service(二)
- 通过html页面打开Android本地的app
- Android ServiceManager启动
- android4.4修改设置界面里,蓝牙默认名称
- 最新百度地图android sdk自定义覆盖物
- 基于Monkey的Android自动化测试
- Android 防止快速 点击 多次
- 【Android4.4蓝牙代码分析】- 蓝牙Enable过程
- Android 多分辨率自适应总结
- Android RIL
- Android屏幕适配方案
- AccessibilityService辅助类用法(Android 中的另类钩子)
- android反编译
- Android的在线解析Json
- 试用友盟SDK实现Android第三方登录(以QQ登录为例)
- Android的本地Json解析
- Android 项目利用 Android Studio 和 Gradle 打包多版本APK