美文网首页
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