zoukankan      html  css  js  c++  java
  • Android开源框架-Annotation框架(以ViewMapping注解为例)

    Annotation 分类

    1 标准 Annotation

    包括Override, Deprecated, SuppressWarnings,标准 Annotation 是指 Java 自带的几个 Annotation,上面三个分别表示重写函数,函数已经被禁止使用,忽略某项 Warning

    2 元 Annotation

    @Retention, @Target, @Inherited, @Documented,元 Annotation 是指用来定义 Annotation 的 Annotation,在后面 Annotation 自定义部分会详细介绍含义

    3 自定义 Annotation

    自定义 Annotation 表示自己根据需要定义的 Annotation,定义时需要用到上面的元 Annotation 这里只是一种分类而已,也可以根据作用域分为源码时、编译时、运行时 Annotation,后面在自定义 Annotation 时会具体介绍

    1.Java.lang包中常用的注解有@Override,@Deprected(已经废弃),@SupressWarning(屏蔽掉一些警告。)我们可以自定义注解。

    2.Java注解之@Retention,@Documented,@Inherited.

    • Retention注解,保留注解说明,这种类型的猪儿会被保留到哪个阶段,有三个值:RetentionPolicy.SOURCE(只有源码级别保留,编译时被忽略),RetentionPolicy.CLASS(class文件中保留,Jvm被忽略),RetentionPolicy.RUNTIME(Jvm保留,所以他们能在运行时被Jvm或者其他运用反射机制的代码所读取和使用)。
    • Document注解,目的就是将这一Annotation的信息显示在JavaAPI文档上,如果吗没有这个注解,在API文档上就不显示Annotation信息。这个注解应该被Javadoc工具记录,javadoc工具在默认情况下不包括注解,如果被注解,会被javadoc之类的工具处理,注解类型的信息也会被包括在生成的文档中。
    • Inherited注解,子类的父类被标记为@Inherited,子类将自动继承父类的所有属性,除了要实现父类接口方法,还要事项Object类中的方法及annotationType()。

    3.java中注解主要的功能是:让开发更易,开发和部署工具可以以某种方式阅读并处理他们。包含注解的程序可以替代额外的Java源文件,XML文件或错误检测机制。

    4.Java中注解的目的是:花更少得 时间在哪些死硬无用的细节中,更多的关注业务逻辑。利用注解可以明显的减少代码量,使得代码的结构清晰。

    5.Java中的反射机制:是Java被视为动态(或者准动态)语言的一个关键性质,这个机制允许程序在运行是通过jdk给出的reflectionAPIs获取任何一个已知名称的class内部信息,包括其modifier(诸如:public,static等),superclass(例如:object),实现interface(例如:cloneable),也包括fileds和methods所有信息,并可以运行改变fields和methods。Java可以加载一个运行时才得知名称的class,获取其完整的结构。

    6.反射机制的功能:获取类的class对象,获取类的fields,获取类的method,获取类的constructor,新建类的实例函数(class<T>的函数newInstance)。

    7.Target里面的ElementType是用来指定Annotation类型可以用在哪些元素上的。例如:TYPE(类型),FIELD(属性),METHOD(方法),PARAMETER(参数),CONSTRUCTOR(构造函数),LOCAL_VARIABLE(局部变量),PACKAGE(包)。其中TYPE类型是指可以用在class,interface,enum,Annotatin类型上。

    下面我们来看一下Android中的ViewMapping注解:

    从上图我们可以看到,在这个注解上面有定义该注解的保留阶段是在Jvm。可以用在类型和属性上面。

    其中定义部分的id()(方法)表示注解接收一个int类型的数据作为id所对应的值(id=R.id.xx)。注解类型不能new对象,viewMapping对象从何而来,Java反射机制,每个继承object类都有getClass方法。通过获取注解类的class,再获取其中的id,然后就可以获取id对应的控件。

    Android客户端用注解来实现findViewById功能及setContentView功能,在Androidplus.jar中的util中有如下代码实现。

    package com.androidplus.util;
    
    import android.app.Activity;
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import java.lang.reflect.Field;
    
    public class ViewMappingUtil
    {
      public static View mapView(Object object, Activity activity)
      {
        Context context = activity;
        ViewMapping viewMapping = (ViewMapping)object.getClass().getAnnotation(ViewMapping.class);
        View rootView = ((LayoutInflater)context.getSystemService("layout_inflater")).inflate(viewMapping.id(), null);
        activity.setContentView(rootView);
        mapView(object, rootView);
        return rootView;
      }
    
      public static void mapView(Object object, View rootView) {
        startReflect(object, rootView, object.getClass());
      }
    
      public static void mapView(Object object, View rootView, int layer) {
        startReflect(object, rootView, object.getClass());
        Class clazz = object.getClass().getSuperclass();
        for (int i = 0; i < layer - 1; ) {
          startReflect(object, rootView, clazz);
    
          ++i; clazz = clazz.getSuperclass();
        }
      }
    
      private static void startReflect(Object object, View rootView, Class<?> clazz)
      {
        Field[] fields = clazz.getDeclaredFields();
    
        Field[] arr$ = fields; int len$ = arr$.length; for (int i$ = 0; i$ < len$; ++i$) { Field field = arr$[i$];
          ViewMapping viewMapping = (ViewMapping)field.getAnnotation(ViewMapping.class);
          int id = 0;
          if (viewMapping != null)
            try {
              id = viewMapping.id();
              field.setAccessible(true);
              field.set(object, rootView.findViewById(id));
            } catch (Exception e) {
              throw new RuntimeException(id + " map error!");
            }
        }
      }
    
      public static View mapView(Object object, Context context)
      {
        return mapView(object, context, null, false);
      }
    
      public static View mapView(Object object, Context context, ViewGroup parent, boolean isAttach) {
        ViewMapping viewMapping = (ViewMapping)object.getClass().getAnnotation(ViewMapping.class);
        View rootView = ((LayoutInflater)context.getSystemService("layout_inflater")).inflate(viewMapping.id(), parent, isAttach);
    
        mapView(object, rootView);
        return rootView;
      }
    }
  • 相关阅读:
    GB28181/RTSP/Ehome协议视频智能分析平台EasyCVR分组后调用接口没有返回对应的通道排查
    【解决方案】基于GB28181/RTSP/HIKSDK/Ehome协议视频智能分析平台EasyCVR搭建司法纪委监委推进智慧留置建设方案
    RTSP/GB28181/SDK/Ehome协议安防视频平台EasyCVR播放视频libDecoder.wasm报404错误码排查过程
    RTSP/GB28181/SDK/Ehome协议安防视频融合平台EasyCVR集成iframe标签报fullscreen error排查过程
    【解决方案】TSINGSEE青犀视频EasyCVR安防视频云平台服务银行自助服务智能监控助力智慧网点建设
    国标GB28181协议视频云平台EasyCVR通过Ehome配置时多端口收流或者单端口收流模式的区别
    【开发记录】国标GB28181/HIKSDK/RTSP/Ehome协议视频融合平台EasyCVR开发定时重启任务
    静态数据成员与静态成员函数
    对象指针
    HDU 1201 Fibonacci Again
  • 原文地址:https://www.cnblogs.com/hupp/p/4705961.html
Copyright © 2011-2022 走看看