美文网首页
Android中注解的使用

Android中注解的使用

作者: 打酱油的小孩 | 来源:发表于2019-03-30 13:02 被阅读0次

    安卓开发中会有很多地方使用到注解,有些是Java中的,有些是三方框架所带的。

    Java中的常见的几种标准注解

    @Override 表示当前的方法定义将覆盖父类中的方法。
    @Deprecated 表示废弃的意思,使用了该注解的方法或者对象,则会有提示。
    @SuppressWarnings 关闭不当的编译器警告信息

    上述几种标准注解我们在安卓开发的过程中经常会看到,不过我们平常使用的注解还有一类并不是Java提供给我们的,而是我们自定义的。自定义注解需要使用到Java提供的几个元注解。元注解是用在注解上的注解。

    Java提供给我们的几个元注解

    @Documented 表示是否将注解信息添加在java文档中
    @Retention 定义该注解的生命周期
    @Target 表示该注解用于什么地方
    @Inherited 定义该注释和子类的关系

    下面着重解释后三个

    1. @Retention

      这个元注解表示他所修饰的注解的生命周期,即需要在什么级别保存该注解信息,
      Retention有一个属性value,是RetentionPolicy类型的,RetentionPolicy是一个枚举
      类型,这个枚举决定了Retention注解应该如何去保持。RetentionPolicy有以下三个值      
      **RetentionPolicy.SOURCE**:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
      **RetentionPolicy.CLASS**:注解被保留到class文件,但jvm加载class文件的时候被遗弃,这是默认的生命周期;
      **RetentionPolicy.RUNTIME**:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
      
    2. @Target
      Target注解说明了他修饰的注解修饰的对象范围,使用的时候类似于
      @Target({ElementType.METHOD})
      ElementType的取值以及含义如下图

      在这里插入图片描述
    3. @Inherited
      在注解上使用@Inherited 表示该注解会被子类继承,注意,仅针对类,成员属性、方法并不受此注释的影响。

    自定义注解的例子:其中的@interface含义为声明新的枚举注解类型

    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface DemoAnnotions{
       
     }
    

    安卓中提供的几个元注解

    安卓在19.1版本开始引入了一个新的注解库,也包含一些元注解供我们使用。
    比如@IntDef & @StringDef,安卓中用@IntDef & @StringDef来代替枚举的使用。
    在日常开发中我们时常会有机会写到枚举,但是枚举是很耗内存的。每一个枚举值都是一个单例对象,在使用它时会增加额外的内存消耗。
    看一个@IntDef替代枚举的例子:

    @IntDef({DemoType.UGC, DemoType.PGC, DemoType.VIDEO, DemoType.IMAGE_TEXT, DemoType.PLAIN_TEXT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface DemoType {
        int UGC = 0;
        int PGC = 1;
        int VIDEO = 2;
        int IMAGE_TEXT = 3;
        int PLAIN_TEXT = 4;
    }
    

    定义@IntDef有两种方式:

    @IntDef({DemoType.UGC, DemoType.PGC, DemoType.VIDEO, DemoType.IMAGE_TEXT, DemoType.PLAIN_TEXT})
    
    @IntDef(flag = true ,value = {DemoType.UGC, DemoType.PGC, DemoType.VIDEO, DemoType.IMAGE_TEXT, DemoType.PLAIN_TEXT})
    

    在安卓中注解肯定不是只有替代枚举这一个作用,事实上我们可以用注解实现非常多的功能。比如我们常用的ButtterKnife中就有很多各种功能的注解。让注解实现一个特定的功能就要说到反射了。

    反射

    1. 反射的定义
      Java反射机制是指在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法。对于任何一个对象,都能够调用它的任何一个方法和属性。这样动态获取新的以及动态调用对象方法的功能就叫做反射。

      在Java中的反射机制,被称为Reflection。它允许运行中的Java程序对自身进行检查,并能直接操作程序的内部属性或方法。Reflection机制允许程序在正在执行的过程中,利用Reflection APIs取得任何已知名称的类的内部信息,包括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、 modifiers等,并可以在执行的过程中,动态生成Instances、变更fields内容或唤起methods。

    2. 安卓中反射作用于注解
      这里我们实现一个小功能来说明反射怎么作用于注解。
      我们首先确定目标,我们实现一个类似于ButterKnife中绑定view的功能,即使用注解代替findViewById的功能。

      第一步先定义注解:

      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.CLASS)
      public @interface MyBindView {
          int value();
      }
      

      第二步写注解解释器

    public void injects(AppCompatActivity activity) {
            Class<? extends AppCompatActivity> clazz = activity.getClass();
            Field[] fields = clazz.getFields();
            if (fields != null && fields.length > 0) {
                for (Field field : fields) {
                    //判断字段是否标注MyBindView
                    MyBindView myBindView = field.getAnnotation(MyBindView.class);
                    if (myBindView != null) {
                        //反射访问私有成员,必须加上这句
                        View view = activity.findViewById(myBindView.value());
                        if (view != null) {
                            try {
                                field.setAccessible(true);
                                field.set(activity, view);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
    
                        }
                    }
                }
            }
        }
    

    使用的时候如下:

       injects(this);
    
       @MyBindView(R.id.account_feedback_btn)
        View feedbackBtn;
    

    这样就类似ButterKnife的@bindView功能了。

    相关文章

      网友评论

          本文标题:Android中注解的使用

          本文链接:https://www.haomeiwen.com/subject/vlvjbqtx.html