当前位置: 首页 > news >正文

韩国情侣网站模板wordpress+悬浮按钮

韩国情侣网站模板,wordpress+悬浮按钮,做网站用html5,北川建设局网站源码细节阅读 上一节根据EventBus的使用流程把实现源码大体梳理了一遍#xff0c;因为精力有限#xff0c;所以看源码都是根据实现过程把基本流程看下#xff0c;中间实现细节先忽略#xff0c;否则越看越深不容易把握大体思路#xff0c;这节把一些细节的部分再看看。 …源码细节阅读 上一节根据EventBus的使用流程把实现源码大体梳理了一遍因为精力有限所以看源码都是根据实现过程把基本流程看下中间实现细节先忽略否则越看越深不容易把握大体思路这节把一些细节的部分再看看。 注解函数查找源码逻辑 #EventBus public void register(Object subscriber) {Class? subscriberClass subscriber.getClass();ListSubscriberMethod subscriberMethods subscriberMethodFinder.findSubscriberMethods(subscriberClass);synchronized (this) {for (SubscriberMethod subscriberMethod : subscriberMethods) {subscribe(subscriber, subscriberMethod);}}}在进行注册的时候我们使用subscriberMethodFinder对象的findSubscriberMethods方法来查找到所有该类中以Subscribe注解的函数以下简称为注解函数。让我们继续看下查找部分的逻辑。 ListSubscriberMethod findSubscriberMethods(Class? subscriberClass) {ListSubscriberMethod subscriberMethods METHOD_CACHE.get(subscriberClass);if (subscriberMethods ! null) {return subscriberMethods;}if (ignoreGeneratedIndex) {subscriberMethods findUsingReflection(subscriberClass);} else {subscriberMethods findUsingInfo(subscriberClass);}if (subscriberMethods.isEmpty()) {throw new EventBusException(Subscriber subscriberClass and its super classes have no public methods with the Subscribe annotation);} else {METHOD_CACHE.put(subscriberClass, subscriberMethods);return subscriberMethods;}}METHOD_CACHE是一个ConcurrentHashMap类型的常量用来保存subscriberClass和对应SubscriberMethod的集合以提高注册效率防止重复查找。 如果METHOD_CACHE缓存中不存在判断变量ignoreGeneratedIndex的值该值是在EventBusBuilder中初始化的表示是否忽略注解生成器默认是false。然后会进入到findUsingInfo函数中进行查找下面再看最后将找到的subscriberMethods添加到METHOD_CACHE中。 private ListSubscriberMethod findUsingInfo(Class? subscriberClass) {FindState findState prepareFindState();findState.initForSubscriber(subscriberClass);return getMethodsAndRelease(findState);}先看findUsingInfo前两行出现一个FindState类它是SubscriberMethodFinder的内部类用来辅助查找订阅事件的方法。 private FindState prepareFindState() {synchronized (FIND_STATE_POOL) {for (int i 0; i POOL_SIZE; i) {FindState state FIND_STATE_POOL[i];if (state ! null) {FIND_STATE_POOL[i] null;return state;}}}return new FindState();}static class FindState {void initForSubscriber(Class? subscriberClass) {this.subscriberClass clazz subscriberClass;skipSuperClasses false;subscriberInfo null;}}prepareFindState()方法主要是返回一个FindState对象先从FIND_STATE_POOL这个缓存池中获取一个现成的如果没有就新建一个对象。获取对象后调用初始化方法将subscriberClass赋值给clazz变量subscriberInfo对象赋值为null。 private ListSubscriberMethod findUsingInfo(Class? subscriberClass) {FindState findState prepareFindState();findState.initForSubscriber(subscriberClass);while (findState.clazz ! null) {findState.subscriberInfo getSubscriberInfo(findState);if (findState.subscriberInfo ! null) {} else {findUsingReflectionInSingleClass(findState);}findState.moveToSuperclass();}return getMethodsAndRelease(findState);}再回到findUsingInfo因为findState.clazz刚赋值过所以不为空。再来看下getSubscriberInfo方法。 private SubscriberInfo getSubscriberInfo(FindState findState) {if (findState.subscriberInfo ! null findState.subscriberInfo.getSuperSubscriberInfo() ! null) {SubscriberInfo superclassInfo findState.subscriberInfo.getSuperSubscriberInfo();if (findState.clazz superclassInfo.getSubscriberClass()) {return superclassInfo;}}if (subscriberInfoIndexes ! null) {for (SubscriberInfoIndex index : subscriberInfoIndexes) {SubscriberInfo info index.getSubscriberInfo(findState.clazz);if (info ! null) {return info;}}}return null;}前面执行initForSubscriber的时候subscriberInfo赋值为null因此第一个if不成立。第二个判断是对象subscriberInfoIndexes该变量也是在EventBusBuilder中初始化的默认是null因此该方法返回值null。 private ListSubscriberMethod findUsingInfo(Class? subscriberClass) {FindState findState prepareFindState();findState.initForSubscriber(subscriberClass);while (findState.clazz ! null) {findState.subscriberInfo getSubscriberInfo(findState);if (findState.subscriberInfo ! null) {} else {findUsingReflectionInSingleClass(findState);}findState.moveToSuperclass();}return getMethodsAndRelease(findState);}再回到findUsingInfo由于getSubscriberInfo返回为null逻辑会走到findUsingReflectionInSingleClass方法中使用反射来获取所有方法下面再看。 获取当前类所有的注解方法后findState.moveToSuperclass()表示修改findState.clazz为subscriberClass的父类Class继续遍历父类中的注解方法。 private static final int MODIFIERS_IGNORE Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;private void findUsingReflectionInSingleClass(FindState findState) {Method[] methods;try {// This is faster than getMethods, especially when subscribers are fat classes like Activitiesmethods findState.clazz.getDeclaredMethods();} catch (Throwable th) {// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149}for (Method method : methods) {int modifiers method.getModifiers();if ((modifiers Modifier.PUBLIC) ! 0 (modifiers MODIFIERS_IGNORE) 0) {Class?[] parameterTypes method.getParameterTypes();if (parameterTypes.length 1) {Subscribe subscribeAnnotation method.getAnnotation(Subscribe.class);if (subscribeAnnotation ! null) {Class? eventType parameterTypes[0];if (findState.checkAdd(method, eventType)) {ThreadMode threadMode subscribeAnnotation.threadMode();findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,subscribeAnnotation.priority(), subscribeAnnotation.sticky()));}}} else if (strictMethodVerification method.isAnnotationPresent(Subscribe.class)) {String methodName method.getDeclaringClass().getName() . method.getName();throw new EventBusException(Subscribe method methodName must have exactly 1 parameter but has parameterTypes.length);}} else if (strictMethodVerification method.isAnnotationPresent(Subscribe.class)) {String methodName method.getDeclaringClass().getName() . method.getName();throw new EventBusException(methodName is a illegal Subscribe method: must be public, non-static, and non-abstract);}}}上面代码流程如下 通过方法getDeclaredMethods()获取该类中所有声明的方法列表遍历方法列表获取方法的修饰符如果修饰符是public并且不是abstract、static等进入下一步MODIFIERS_IGNORE定义如第一行代码获取方法的参数列表如果参数的个数是1并且使用了Subscribe注解获取唯一的入参进行下一步然后checkAdd()方法用来判断FindState的anyMethodByEventType map是否已经添加过以当前eventType为key的键值对没添加过则返回true就是看看当前类中有没有多个事件相同的注解函数通过注解对象subscribeAnnotation获取threadMode然后新建SubscriberMethod添加到findState.subscriberMethods集合中。 分析完findUsingReflectionInSingleClass这个方法后我们回到findUsingInfo。 private ListSubscriberMethod findUsingInfo(Class? subscriberClass) {FindState findState prepareFindState();findState.initForSubscriber(subscriberClass);while (findState.clazz ! null) {findState.subscriberInfo getSubscriberInfo(findState);if (findState.subscriberInfo ! null) {} else {findUsingReflectionInSingleClass(findState);}findState.moveToSuperclass();}return getMethodsAndRelease(findState);}遍历当前类及其父类通过findUsingReflectionInSingleClass方法找到所有注解方法后通过getMethodsAndRelease返回所有相关方法。 private ListSubscriberMethod getMethodsAndRelease(FindState findState) {ListSubscriberMethod subscriberMethods new ArrayList(findState.subscriberMethods);findState.recycle();synchronized (FIND_STATE_POOL) {for (int i 0; i POOL_SIZE; i) {if (FIND_STATE_POOL[i] null) {FIND_STATE_POOL[i] findState;break;}}}return subscriberMethods;}通过上面的解析知道所有的SubscriberMethod都添加到findState.subscriberMethods集合中这个方法就是把findState.subscriberMethods集合中的内容复制出来然后释放findState中的资源并把findState放到FIND_STATE_POOL缓存中POOL_SIZE常量是4这样下次查找的时候可以重复利用无需每次都新建对象。 以上为注解方法查找的过程。在上面分析的过程中出现了两个变量subscriberInfoIndexes和ignoreGeneratedIndex看样子都是关于索引的分析的时候都是使用的EventBusBuilder中的默认值。看下subscriberInfoIndexes赋值的地方看注释意思是将EventBus注解处理器生成索引添加添加进来。所以注解处理器需要再了解下。 /** Adds an index generated by EventBus annotation preprocessor. */public EventBusBuilder addIndex(SubscriberInfoIndex index) {if (subscriberInfoIndexes null) {subscriberInfoIndexes new ArrayList();}subscriberInfoIndexes.add(index);return this;}Subscriber Index注解处理器 通过上面分析可知EventBus注册事件时主要是在项目运行时通过反射来查找注解方法信息如果项目中有大量的注解方法必然会对项目运行时的性能产生影响。 除了在项目运行时通过反射查找注解方法信息EventBus 还提供了在项目编译时通过注解处理器查找注解方法信息的方式生成一个辅助的索引类来保存这些信息这个索引类就是Subscriber Index。 1、Subscriber Index使用方式 首先要在 app 的build.gradle中加入如下配置 android {defaultConfig {javaCompileOptions {annotationProcessorOptions {// 指定辅助索引类的名称和包名注意这个类时自动生成的不需要我们写arguments [ eventBusIndex : com.jane.demo.MyEventBusIndex ]}}} } dependencies {compile org.greenrobot:eventbus:3.3.1// 引入注解处理器annotationProcessor org.greenrobot:eventbus-annotation-processor:3.3.1 }在项目的Application中添加如下配置以生成一个默认的 EventBus 单例 EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();此时重新编译下项目会生成一个MyEventBusIndex类不同的gradle版本生成的位置可能不一样。 生成的MyEventBusIndex代码如下 public class MyEventBusIndex implements SubscriberInfoIndex {private static final MapClass?, SubscriberInfo SUBSCRIBER_INDEX;static {SUBSCRIBER_INDEX new HashMapClass?, SubscriberInfo();putIndex(new SimpleSubscriberInfo(EventBusService.class, true, new SubscriberMethodInfo[] {new SubscriberMethodInfo(onMsgEventReceived, String.class),new SubscriberMethodInfo(onMsgEventReceived, MsgEvent.class),new SubscriberMethodInfo(onMsgEventReceived, org.greenrobot.eventbus.NoSubscriberEvent.class),}));putIndex(new SimpleSubscriberInfo(EventBusActivity.class, true, new SubscriberMethodInfo[] {new SubscriberMethodInfo(onMsgEventReceived, Event.class),}));}private static void putIndex(SubscriberInfo info) {SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);}Overridepublic SubscriberInfo getSubscriberInfo(Class? subscriberClass) {SubscriberInfo info SUBSCRIBER_INDEX.get(subscriberClass);if (info ! null) {return info;} else {return null;}} }代码中SUBSCRIBER_INDEX是一个HashMap保存了当前注册类的Class类型和其中注解方法的信息。 2、Subscriber Index源码 EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();使用的时候获取EventBusBuilder对象然后调用addIndex方法把生成的MyEventBusIndex加入进去。 /** Adds an index generated by EventBus annotation preprocessor. */public EventBusBuilder addIndex(SubscriberInfoIndex index) {if (subscriberInfoIndexes null) {subscriberInfoIndexes new ArrayList();}subscriberInfoIndexes.add(index);return this;}上面的方法是不是比较眼熟就是上面代码分析的时候出现的变量subscriberInfoIndexes赋值函数。这样运行的时候就把之前编译好的索引类的实例保存在subscriberInfoIndexes集合中。然后调用installDefaultEventBus方法创建EventBus实例。 /*** Installs the default EventBus returned by {link EventBus#getDefault()} using this builders values. Must be* done only once before the first usage of the default EventBus.** throws EventBusException if theres already a default EventBus instance in place*/public EventBus installDefaultEventBus() {synchronized (EventBus.class) {if (EventBus.defaultInstance ! null) {throw new EventBusException(Default instance already exists. It may be only set once before its used the first time to ensure consistent behavior.);}EventBus.defaultInstance build();return EventBus.defaultInstance;}}/** Builds an EventBus based on the current configuration. */public EventBus build() {return new EventBus(this);}上面通过build方法以当前EventBusBuilder对象作为参数生成EventBus单例对象并赋值给defaultInstance这样就把subscriberInfoIndexes信息传递给了EventBus。以后调用EventBus 的getDefault()返回的就是这里生成的单例对象里面包含了subscriberInfoIndexes信息。 而且在Application中生成了 EventBus 的默认单例这样就保证了在项目其它地方执行EventBus.getDefault()就能得到就是上面包含subscriberInfoIndexes信息的单例。 在上面分析查找注解函数的时候分析过一个函数 private ListSubscriberMethod findUsingInfo(Class? subscriberClass) {FindState findState prepareFindState();findState.initForSubscriber(subscriberClass);while (findState.clazz ! null) {findState.subscriberInfo getSubscriberInfo(findState);if (findState.subscriberInfo ! null) {····} else {findUsingReflectionInSingleClass(findState);}findState.moveToSuperclass();}return getMethodsAndRelease(findState);}如果没有使用注解处理器的话getSubscriberInfo这个方法返回值是null因此会走到findUsingReflectionInSingleClass通过反射区获取注解方法。现在使用使用注解处理器的话在重新看下这个函数。 private SubscriberInfo getSubscriberInfo(FindState findState) {if (findState.subscriberInfo ! null findState.subscriberInfo.getSuperSubscriberInfo() ! null) {SubscriberInfo superclassInfo findState.subscriberInfo.getSuperSubscriberInfo();if (findState.clazz superclassInfo.getSubscriberClass()) {return superclassInfo;}}//不为空if (subscriberInfoIndexes ! null) {for (SubscriberInfoIndex index : subscriberInfoIndexes) {SubscriberInfo info index.getSubscriberInfo(findState.clazz);if (info ! null) {return info;}}}return null;}Overridepublic SubscriberInfo getSubscriberInfo(Class? subscriberClass) {SubscriberInfo info SUBSCRIBER_INDEX.get(subscriberClass);if (info ! null) {return info;} else {return null;}}如果使用了注解处理器因为subscriberInfoIndexes这个集合不为空遍历获取当前类对应的注解方法列表 index.getSubscriberInfo这个方法实际调用的就是系统生成的MyEventBusIndex中的getSubscriberInfo方法这样就获取到了之前编译生成的注解方法。 private ListSubscriberMethod findUsingInfo(Class? subscriberClass) {FindState findState prepareFindState();findState.initForSubscriber(subscriberClass);while (findState.clazz ! null) {findState.subscriberInfo getSubscriberInfo(findState);if (findState.subscriberInfo ! null) {SubscriberMethod[] array findState.subscriberInfo.getSubscriberMethods();for (SubscriberMethod subscriberMethod : array) {if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {findState.subscriberMethods.add(subscriberMethod);}}} else {findUsingReflectionInSingleClass(findState);}findState.moveToSuperclass();}return getMethodsAndRelease(findState);}通过getSubscriberInfo返回当前类所有注解方法后遍历所有订阅了事件的方法然后加入到subscriberMethods列表中其它的和之前的注册流程一样。 参考文章 EventBus 原理解析
http://www.w-s-a.com/news/95741/

相关文章:

  • 上海网站建设公司排行建设无障碍网站
  • phpcms网站打不开网页制作网站设计稿
  • 博客网站开发环境wordpress 中英文双语
  • 做网站报价表群辉装wordpress
  • 请人做游戏的网站视觉设计师的工作内容
  • 昆明网站建设知名企业博客网站开发
  • 如何做网站网页免费thinkphp网站后台模板
  • 怎么自己做优惠券网站济南小程序开发
  • 南昌网站专业制作做仿站如何获取网站源码
  • qq钓鱼网站wordpress 企业站模板
  • 推进文明网站建设免费设计公司logo设计
  • 做电脑租赁网站server 2008 网站部署
  • 做网站的公司一年能赚多少钱wordpress作者增加分类插件
  • 苏州尚云网站建设专业摄影网站推荐
  • 020网站开发微信公众号直接链接网站怎么做
  • 学做烘焙的网站某网站注册需要邮箱是怎么弄
  • 网站的特效代码公司网站开发的工作内容
  • 网站制作哪家好商城网站建设预算要多少钱
  • 怎么做律所的官方网站微网站可以做商城吗
  • 通用网站后台管理系统(php版)网站备案ip查询网站查询
  • 制作网站代码吗江阴网站建设推广
  • 汕头建网站wordpress文章网址采集
  • 十大景观设计网站用vue框架做的网站
  • 福建省建设监理网官方网站做外贸网站卖什么东西好
  • 公司做网站排名东莞关键词优化推广
  • 连云港做企业网站公司全网营销与seo
  • 电子毕业设计代做网站wordpress 插件放在那
  • 黄石规划建设局网站怎么做存储网站
  • 网站安装wordpress滨江网站建设
  • 河南官网网站建设一般使用的分辨率显示密度是