美文网首页
Android自定义注解(反射+运行时注解)

Android自定义注解(反射+运行时注解)

作者: Amy_LuLu__ | 来源:发表于2018-02-09 18:22 被阅读0次

注意:本篇文章是本人阅读相关文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。

本篇文章内容来自于
Android高级进阶 顾浩鑫
Android中的自定义注解(反射实现-运行时注解)

目录

  1. 元注解
  2. 反射+运行时注解实现

1. 元注解

元注解,就是用来定义和实现注解的注解。
总共有五种。

1⃣️@Target 用来指定注解所适用的对象范围
如果一个注解的定义没有使用@Target修饰,那么它可以用在除了TYPE_USE和TYPE_PARAMEYER之外的其他类型中。

@Target参数取值

//注解参数取值是一个ElementType类型的数组。
元素类型    适用于
ANNOTATION_TYPE 注解类型声明
CONSTRUCTOR 构造函数
FIELD   实例变量
LOCAL_VARIABLE  局部变量
METHOD  方法
PACKAGE 包
PARAMETER   方法参数或者构造函数的参数
TYPE    类(包含enmu)和接口(包含注解类型)
TYPE_PARAMETER  类型参数
TYPE_USER   类型的用图

使用案例

@Target({ElementType.TYPE,ElementType.PACKAGE})
public @interface CrashReport

2⃣️@Retention:用来指明注解的访问范围
也就是在什么级别保留注解
未指定类型时,默认是CLASS类型。

参数取值

源码级注解:
在定义注解接口时,使用@Retention(RetentionPolicy.SOURCE)修饰的注解,
该类型的注解信息只会保留在.java源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的.class文件中。

编译时注解:
在定义注解接口时,使用@Retention(RetentionPolicy.CLASS)修饰的注解,
该注解的注册信息会保留在.java源码里和.class文件里,在执行的时候,会被Java虚拟机丢弃,不会加载到虚拟机种。

运行时注解:
在定义注解接口时,使用@Retention(RetentionPolicy.RUNTIME)修饰的注解,
Java虚拟机在运行期也保留注解信息,可以通过反射机制读取注解的信息(.java源码,.class文件和执行的时候都有注解的信息)

3⃣️@Documented:表示被修饰的注解应该被包含在被注解项的文档中。
例如用JavaDoc生成的文档

4⃣️@Inherited:表示该注解可以被子类继承的。

5⃣️@Repeatable:表示这个注解可以在同一个项上面应用多次
不过这个注解是在Java8中才引入的,前面四个元注解都是在Java5中就已经引入的。

2. 反射+运行时注解实现

这里只是基本使用
更多可以看Android中的自定义注解(反射实现-运行时注解)

第一步:创建自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();
}

第二步:使用自定义注解

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        injectContentView(this); //在该方法中进行反射
    }
}

第三步:使用反射来处理注解

    private void injectContentView(Activity activity) {
        Class clazz = activity.getClass();
        //如果ContentView这个注解使用了
        if (clazz.isAnnotationPresent(ContentView.class)) {
            // 得到activity这个类的ContentView注解
            ContentView contentView = (ContentView) clazz.getAnnotation(ContentView.class);
            // 得到注解的值  
            int layoutId = contentView.value();
            // 使用反射调用setContentView
            try {
                Method method = clazz.getMethod("setContentView", int.class);
                method.setAccessible(true);
                method.invoke(activity,layoutId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

相关文章

网友评论

      本文标题:Android自定义注解(反射+运行时注解)

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