快速开发之xUtils(二)ViewUtils详细介绍

11 篇文章 0 订阅

转载:http://www.apkbus.com/forum.php?mod=viewthread&tid=157641&highlight=xUtils

案例下载:http://download.csdn.net/detail/huningjun/8645595或者https://github.com/wyouflf/xUtils

xUtils可以减少我们很多重复性的工作,加快我们的开发速度。但是我们很有必要去了解一下它到底是怎么实现的。
因为需求总是变化的。可能有一天,我们需要去修改里面的一些东西。所以不但要知其然,还要知其所以然。
   view创建以后,xUtils只调用了以下这个方法,就实现了注入view和事件。
   ViewUtils.inject(this,view); //注入view和事件
   它到底做了什么事情呢?它的具体代码如下:
     
  1. @SuppressWarnings("ConstantConditions")
  2.     private static void injectObject(Object handler, ViewFinder finder) {

  3.         // 注入view
  4.         Field[] fields = handler.getClass().getDeclaredFields();
  5.         if (fields != null && fields.length > 0) {
  6.             for (Field field : fields) {
  7.                 //得到注解
  8.                 ViewInject viewInject = field.getAnnotation(ViewInject.class);
  9.                 if (viewInject != null) {
  10.                     try {
  11.                         //根据id找到view
  12.                         View view = finder.findViewById(viewInject.value(), viewInject.parentId());
  13.                         if (view != null) {
  14.                             field.setAccessible(true);
  15.                             //绑定view
  16.                             field.set(handler, view);
  17.                         }
  18.                     } catch (Throwable e) {
  19.                         LogUtils.e(e.getMessage(), e);
  20.                     }
  21.                 } else {
  22.                 //得到注解
  23.                     ResInject resInject = field.getAnnotation(ResInject.class);
  24.                     if (resInject != null) {
  25.                         try {
  26.                         //根据id和资源类型load资源
  27.                             Object res = ResLoader.loadRes(
  28.                                     resInject.type(), finder.getContext(), resInject.id());
  29.                             if (res != null) {
  30.                                 field.setAccessible(true);
  31.                                 field.set(handler, res);
  32.                             }
  33.                         } catch (Throwable e) {
  34.                             LogUtils.e(e.getMessage(), e);
  35.                         }
  36.                     } else {
  37.                         //得到注解
  38.                         PreferenceInject preferenceInject = field.getAnnotation(PreferenceInject.class);
  39.                         if (preferenceInject != null) {
  40.                             try {
  41.                                 根据id找到对应的Preference
  42.                                 Preference preference = finder.findPreference(preferenceInject.value());
  43.                                 if (preference != null) {
  44.                                     field.setAccessible(true);
  45.                                     field.set(handler, preference);
  46.                                 }
  47.                             } catch (Throwable e) {
  48.                                 LogUtils.e(e.getMessage(), e);
  49.                             }
  50.                         }
  51.                     }
  52.                 }
  53.             }
  54.         }

  55.         // 注入事件
  56.         Method[] methods = handler.getClass().getDeclaredMethods();
  57.         if (methods != null && methods.length > 0) {
  58.             String eventName = OnClick.class.getCanonicalName();
  59.             String prefix = eventName.substring(0, eventName.lastIndexOf('.'));
  60.             DoubleKeyValueMap<ViewInjectInfo, Annotation, Method> info_annotation_method_map = new DoubleKeyValueMap<ViewInjectInfo, Annotation, Method>();
  61.             for (Method method : methods) {
  62.                 Annotation[] annotations = method.getDeclaredAnnotations();
  63.                 if (annotations != null && annotations.length > 0) {
  64.                     for (Annotation annotation : annotations) {
  65.                         Class<?> annType = annotation.annotationType();
  66.                         if (annType.getAnnotation(EventBase.class) != null) {
  67.                             if (annType.getCanonicalName().startsWith(prefix)) {
  68.                                 try {
  69.                                     // ProGuard:-keep class * extends java.lang.annotation.Annotation { *; }
  70.                                     Method valueMethod = annType.getDeclaredMethod("value");
  71.                                     Method parentIdMethod = null;
  72.                                     try {
  73.                                         parentIdMethod = annType.getDeclaredMethod("parentId");
  74.                                     } catch (Throwable e) {
  75.                                     }
  76.                                     Object values = valueMethod.invoke(annotation);
  77.                                     Object parentIds = parentIdMethod == null ? null : parentIdMethod.invoke(annotation);
  78.                                     int parentIdsLen = parentIds == null ? 0 : Array.getLength(parentIds);
  79.                                     int len = Array.getLength(values);
  80.                                     for (int i = 0; i < len; i++) {
  81.                                         ViewInjectInfo info = new ViewInjectInfo();
  82.                                         info.value = Array.get(values, i);
  83.                                         info.parentId = parentIdsLen > i ? (Integer) Array.get(parentIds, i) : 0;
  84.                                         info_annotation_method_map.put(info, annotation, method);
  85.                                     }
  86.                                 } catch (Throwable e) {
  87.                                     LogUtils.e(e.getMessage(), e);
  88.                                 }
  89.                             } else {
  90.                                 ViewCustomEventListener listener = annotationType_viewCustomEventListener_map.get(annType);
  91.                                 if (listener != null) {
  92.                                     listener.setEventListener(handler, finder, annotation, method);
  93.                                 }
  94.                             }
  95.                         }
  96.                     }
  97.                 }
  98.             }
  99.             ViewCommonEventListener.setAllEventListeners(handler, finder, info_annotation_method_map);
  100.         }
  101.     }
复制代码

                               

    其实实现非常简单。首先是根据反射获得类的所有字段然后根据注解,得到控件的id,然后在view里找到控件。然后field.setAccessible(true);
field.set(handler,res);让声明的控件,和view里的控件关联起来。
    资源类或根据资源id和资源类型加载到对应的资源。方法如下:ResLoader.loadRes(resInject.type(),finder.getContext(), resInject.id());
    Preference也会根据id找到对应的值。
    绑定事件的方式也是类似。代码如下:
  1. @SuppressWarnings("ConstantConditions")
  2.     public static void setAllEventListeners(
  3.             Object handler,
  4.             ViewFinder finder,
  5.             DoubleKeyValueMap<ViewInjectInfo, Annotation, Method> info_annotation_method_map) {

  6.         for (ViewInjectInfo info : info_annotation_method_map.getFirstKeys()) {
  7.             ConcurrentHashMap<Annotation, Method> annotation_method_map = info_annotation_method_map.get(info);
  8.             for (Annotation annotation : annotation_method_map.keySet()) {
  9.                 try {
  10.                     Method method = annotation_method_map.get(annotation);
  11.                     if (annotation instanceof OnClick) {
  12.                         View view = finder.findViewByInfo(info);
  13.                         if (view == null) break;
  14.                         //view.setOnClickListener(new ViewCommonEventListener(handler, method));
  15.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  16.                         setEventListener(view, "setOnClickListener", OnClickListener.class, listener);
  17.                     } else if (annotation instanceof OnLongClick) {
  18.                         View view = finder.findViewByInfo(info);
  19.                         if (view == null) break;
  20.                         //view.setOnLongClickListener(new ViewCommonEventListener(handler, method));
  21.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  22.                         setEventListener(view, "setOnLongClickListener", OnLongClickListener.class, listener);
  23.                     } else if (annotation instanceof OnFocusChange) {
  24.                         View view = finder.findViewByInfo(info);
  25.                         if (view == null) break;
  26.                         //view.setOnFocusChangeListener(new ViewCommonEventListener(handler, method));
  27.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  28.                         setEventListener(view, "setOnFocusChangeListener", OnFocusChangeListener.class, listener);
  29.                     } else if (annotation instanceof OnKey) {
  30.                         View view = finder.findViewByInfo(info);
  31.                         if (view == null) break;
  32.                         //view.setOnKeyListener(new ViewCommonEventListener(handler, method));
  33.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  34.                         setEventListener(view, "setOnKeyListener", OnKeyListener.class, listener);
  35.                     } else if (annotation instanceof OnTouch) {
  36.                         View view = finder.findViewByInfo(info);
  37.                         if (view == null) break;
  38.                         //view.setOnTouchListener(new ViewCommonEventListener(handler, method));
  39.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  40.                         setEventListener(view, "setOnTouchListener", OnTouchListener.class, listener);
  41.                     } else if (annotation instanceof OnItemClick) {
  42.                         View view = finder.findViewByInfo(info);
  43.                         if (view == null) break;
  44.                         //((AdapterView<?>) view).setOnItemClickListener(new ViewCommonEventListener(handler, method));
  45.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  46.                         setEventListener(view, "setOnItemClickListener", OnItemClickListener.class, listener);
  47.                     } else if (annotation instanceof OnItemLongClick) {
  48.                         View view = finder.findViewByInfo(info);
  49.                         if (view == null) break;
  50.                         //((AdapterView<?>) view).setOnItemLongClickListener(new ViewCommonEventListener(handler, method));
  51.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  52.                         setEventListener(view, "setOnItemLongClickListener", OnItemLongClickListener.class, listener);
  53.                     } else if (annotation instanceof OnChildClick) {
  54.                         View view = finder.findViewByInfo(info);
  55.                         if (view == null) break;
  56.                         //((ExpandableListView) view).setOnChildClickListener(new ViewCommonEventListener(handler, method));
  57.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  58.                         setEventListener(view, "setOnChildClickListener", ExpandableListView.OnChildClickListener.class, listener);
  59.                     } else if (annotation instanceof OnGroupClick) {
  60.                         View view = finder.findViewByInfo(info);
  61.                         if (view == null) break;
  62.                         //((ExpandableListView) view).setOnGroupClickListener(new ViewCommonEventListener(handler, method));
  63.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  64.                         setEventListener(view, "setOnGroupClickListener", ExpandableListView.OnGroupClickListener.class, listener);
  65.                     } else if (annotation instanceof OnGroupCollapse) {
  66.                         View view = finder.findViewByInfo(info);
  67.                         if (view == null) break;
  68.                         //((ExpandableListView) view).setOnGroupCollapseListener(new ViewCommonEventListener(handler, method));
  69.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  70.                         setEventListener(view, "setOnGroupCollapseListener", ExpandableListView.OnGroupCollapseListener.class, listener);
  71.                     } else if (annotation instanceof OnGroupExpand) {
  72.                         View view = finder.findViewByInfo(info);
  73.                         if (view == null) break;
  74.                         //((ExpandableListView) view).setOnGroupExpandListener(new ViewCommonEventListener(handler, method));
  75.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  76.                         setEventListener(view, "setOnGroupExpandListener", ExpandableListView.OnGroupExpandListener.class, listener);
  77.                     } else if (annotation instanceof OnCheckedChange) {
  78.                         View view = finder.findViewByInfo(info);
  79.                         if (view == null) break;
  80.                         if (view instanceof RadioGroup) {
  81.                             //((RadioGroup) view).setOnCheckedChangeListener(new ViewCommonEventListener(handler, method));
  82.                             ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  83.                             setEventListener(view, "setOnCheckedChangeListener", RadioGroup.OnCheckedChangeListener.class, listener);
  84.                         } else if (view instanceof CompoundButton) {
  85.                             //((CompoundButton) view).setOnCheckedChangeListener(new ViewCommonEventListener(handler, method));
  86.                             ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  87.                             setEventListener(view, "setOnCheckedChangeListener", CompoundButton.OnCheckedChangeListener.class, listener);
  88.                         }
  89.                     } else if (annotation instanceof OnPreferenceClick) {
  90.                         Preference preference = finder.findPreference(info.value.toString());
  91.                         if (preference == null) break;
  92.                         //preference.setOnPreferenceClickListener(new ViewCommonEventListener(handler, method));
  93.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  94.                         setEventListener(preference, "setOnPreferenceClickListener", Preference.OnPreferenceClickListener.class, listener);
  95.                     } else if (annotation instanceof OnPreferenceChange) {
  96.                         Preference preference = finder.findPreference(info.value.toString());
  97.                         if (preference == null) break;
  98.                         //preference.setOnPreferenceChangeListener(new ViewCommonEventListener(handler, method));
  99.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  100.                         setEventListener(preference, "setOnPreferenceChangeListener", Preference.OnPreferenceChangeListener.class, listener);
  101.                     } else if (annotation instanceof OnTabChange) {
  102.                         View view = finder.findViewByInfo(info);
  103.                         if (view == null) break;
  104.                         //((TabHost) view).setOnTabChangedListener(new ViewCommonEventListener(handler, method));
  105.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  106.                         setEventListener(view, "setOnTabChangedListener", TabHost.OnTabChangeListener.class, listener);
  107.                     } else if (annotation instanceof OnScrollChanged) {
  108.                         View view = finder.findViewByInfo(info);
  109.                         if (view == null) break;
  110.                         //view.getViewTreeObserver().addOnScrollChangedListener(new ViewCommonEventListener(handler, method));
  111.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method);
  112.                         setEventListener(view, "addOnScrollChangedListener", ViewTreeObserver.OnScrollChangedListener.class, listener);
  113.                     } else if (annotation instanceof OnScrollStateChanged) {
  114.                         View view = finder.findViewByInfo(info);
  115.                         if (view == null) break;
  116.                         Method method0 = null, method1 = null;
  117.                         ConcurrentHashMap<Annotation, Method> a_m_map = info_annotation_method_map.get(info);
  118.                         for (Annotation a : a_m_map.keySet()) {
  119.                             if (a instanceof OnScrollStateChanged) {
  120.                                 method0 = a_m_map.get(a);
  121.                             } else if (a instanceof OnScroll) {
  122.                                 method1 = a_m_map.get(a);
  123.                             }
  124.                         }
  125.                         //((AbsListView) view).setOnScrollListener(new ViewCommonEventListener(handler, method0, method1));
  126.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method0, method1);
  127.                         setEventListener(view, "setOnScrollListener", AbsListView.OnScrollListener.class, listener);
  128.                     } else if (annotation instanceof OnItemSelected) {
  129.                         View view = finder.findViewByInfo(info);
  130.                         if (view == null) break;
  131.                         Method method0 = null, method1 = null;
  132.                         ConcurrentHashMap<Annotation, Method> a_m_map = info_annotation_method_map.get(info);
  133.                         for (Annotation a : a_m_map.keySet()) {
  134.                             if (a instanceof OnItemSelected) {
  135.                                 method0 = a_m_map.get(a);
  136.                             } else if (a instanceof OnNothingSelected) {
  137.                                 method1 = a_m_map.get(a);
  138.                             }
  139.                         }
  140.                         //((AdapterView<?>) view).setOnItemSelectedListener(new ViewCommonEventListener(handler, method0, method1));
  141.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method0, method1);
  142.                         setEventListener(view, "setOnItemSelectedListener", AbsListView.OnItemSelectedListener.class, listener);
  143.                     } else if (annotation instanceof OnProgressChanged) {
  144.                         View view = finder.findViewByInfo(info);
  145.                         if (view == null) break;
  146.                         Method method0 = null, method1 = null, method2 = null;
  147.                         ConcurrentHashMap<Annotation, Method> a_m_map = info_annotation_method_map.get(info);
  148.                         for (Annotation a : a_m_map.keySet()) {
  149.                             if (a instanceof OnProgressChanged) {
  150.                                 method0 = a_m_map.get(a);
  151.                             } else if (a instanceof OnStartTrackingTouch) {
  152.                                 method1 = a_m_map.get(a);
  153.                             } else if (a instanceof OnStopTrackingTouch) {
  154.                                 method2 = a_m_map.get(a);
  155.                             }
  156.                         }
  157.                         //((SeekBar) view).setOnSeekBarChangeListener(new ViewCommonEventListener(handler, method0, method1, method2));
  158.                         ViewCommonEventListener listener = new ViewCommonEventListener(handler, method0, method1, method2);
  159.                         setEventListener(view, "setOnSeekBarChangeListener", SeekBar.OnSeekBarChangeListener.class, listener);
  160.                     }
  161.                 } catch (Throwable e) {
  162.                     LogUtils.e(e.getMessage(), e);
  163.                 }
  164.             }
  165.         }
  166.     }

  167.     private static void setEventListener(Object view,
  168.                                          String setEventListenerMethod,
  169.                                          Class<?> eventListenerType,
  170.                                          ViewCommonEventListener listener) {
  171.         try {
  172.             Method setMethod = view.getClass().getMethod(setEventListenerMethod, eventListenerType);
  173.             if (setMethod != null) {
  174.                 setMethod.invoke(view, listener);
  175.             }
  176.         } catch (Throwable e) {
  177.             LogUtils.e(e.getMessage(), e);
  178.         }
  179.     }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 目标检测的定义 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 目标检测任务可分为两个关键的子任务,目标定位和目标分类。首先检测图像中目标的位置(目标定位),然后给出每个目标的具体类别(目标分类)。输出结果是一个边界框(称为Bounding-box,一般形式为(x1,y1,x2,y2),表示框的左上角坐标和右下角坐标),一个置信度分数(Confidence Score),表示边界框中是否包含检测对象的概率和各个类别的概率(首先得到类别概率,经过Softmax可得到类别标签)。 1.1 Two stage方法 目前主流的基于深度学习的目标检测算法主要分为两类:Two stage和One stage。Two stage方法将目标检测过程分为两个阶段。第一个阶段是 Region Proposal 生成阶段,主要用于生成潜在的目标候选框(Bounding-box proposals)。这个阶段通常使用卷积神经网络(CNN)从输入图像中提取特征,然后通过一些技巧(如选择性搜索)来生成候选框。第个阶段是分类和位置精修阶段,将第一个阶段生成的候选框输入到另一个 CNN 中进行分类,并根据分类结果对候选框的位置进行微调。Two stage 方法的优点是准确度较高,缺点是速度相对较慢。 常见Tow stage目标检测算法有:R-CNN系列、SPPNet等。 1.2 One stage方法 One stage方法直接利用模型提取特征值,并利用这些特征值进行目标的分类和定位,不需要生成Region Proposal。这种方法的优点是速度快,因为省略了Region Proposal生成的过程。One stage方法的缺点是准确度相对较低,因为它没有对潜在的目标进行预先筛选。 常见的One stage目标检测算法有:YOLO系列、SSD系列和RetinaNet等。 2 常见名词解释 2.1 NMS(Non-Maximum Suppression) 目标检测模型一般会给出目标的多个预测边界框,对成百上千的预测边界框都进行调整肯定是不可行的,需要对这些结果先进行一个大体的挑选。NMS称为非极大值抑制,作用是从众多预测边界框中挑选出最具代表性的结果,这样可以加快算法效率,其主要流程如下: 设定一个置信度分数阈值,将置信度分数小于阈值的直接过滤掉 将剩下框的置信度分数从大到小排序,选中值最大的框 遍历其余的框,如果和当前框的重叠面积(IOU)大于设定的阈值(一般为0.7),就将框删除(超过设定阈值,认为两个框的里面的物体属于同一个类别) 从未处理的框中继续选一个置信度分数最大的,重复上述过程,直至所有框处理完毕 2.2 IoU(Intersection over Union) 定义了两个边界框的重叠度,当预测边界框和真实边界框差异很小时,或重叠度很大时,表示模型产生的预测边界框很准确。边界框A、B的IOU计算公式为: 2.3 mAP(mean Average Precision) mAP即均值平均精度,是评估目标检测模型效果的最重要指标,这个值介于0到1之间,且越大越好。mAP是AP(Average Precision)的平均值,那么首先需要了解AP的概念。想要了解AP的概念,还要首先了解目标检测中Precision和Recall的概念。 首先我们设置置信度阈值(Confidence Threshold)和IoU阈值(一般设置为0.5,也会衡量0.75以及0.9的mAP值): 当一个预测边界框被认为是True Positive(TP)时,需要同时满足下面三个条件: Confidence Score > Confidence Threshold 预测类别匹配真实值(Ground truth)的类别 预测边界框的IoU大于设定的IoU阈值 不满足条件2或条件3,则认为是False Positive(FP)。当对应同一个真值有多个预测结果时,只有最高置信度分数的预测结果被认为是True Positive,其余被认为是False Positive。 Precision和Recall的概念如下图所示: Precision表示TP与预测边界框数量的比值 Recall表示TP与真实边界框数量的比值 改变不同的置信度阈值,可以获得多组Precision和Recall,Recall放X轴,Precision放Y轴,可以画出一个Precision-Recall曲线,简称P-R
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值