美文网首页android开发技巧
Android 开发也要掌握的Java知识 - Java注解

Android 开发也要掌握的Java知识 - Java注解

作者: 进击的包籽 | 来源:发表于2020-08-17 01:13 被阅读0次
  • Android开发中大量的使用了注解,开源框架也大量使用,我们自己虽然自定义的注解不多,但也要了解基本的知识。

1.注解的定义

  • Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 注解是元数据的一种形式,提供有关
    于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。

2.注解是什么样的

  • Java中所有的注解,默认实现 “Annotation ”接口
package java.lang.annotation;
 
public interface Annotation {
    boolean equals(Object obj);
 
    int hashCode();
 
    String toString();
 
    Class<? extends Annotation> annotationType();
}
  • 平时我们见到的最多就是重写注解吧,只要子类重写了父类的方法,都会出现这个注解。
@Override
  • 看看这个 “@Override” 源码,注解的写法是 “@interface” ,跟接口有没有很像?,但前面多了一个 “ @” 符号
  • 而且这个注解上面还有注解,这就是元注解
image.png

3.注解的分类以及作用

  • 我这里整理了一些,自己写注解,不熟悉就翻来看看,用的多久熟悉了
注解的分类

4.注解写法

  • 只有一个默认参数value 时,可以不写参数“key = ”,以下两种写法一样样效果
//作用在什么地方:类、接口、方法、属性变量
@Target({ElementType.TYPE,ElementType.METHOD, ElementType.FIELD})
//生命周期在运行时
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
        //如果使用value,用的时候可以是  “value = 111”,也可以直接写 “111”
        int value();   
}
 
@TestAnnotation(111)
private int num1;
 
@TestAnnotation(value = 111)
private int num2;
  • 如果要传入的参数不止一个,那么 “value = 111” 就一定要写全
  • 如果有“default”默认参数了,就可以不用传参
  • “default”也可以再传参覆盖原来的值
//作用在什么地方:类、接口、方法、属性变量
@Target({ElementType.TYPE,ElementType.METHOD, ElementType.FIELD})
//生命周期在运行时
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
        //如果使用value,用的时候可以是value = 111,也可以直接写 111
        int value();

        //自己创建一个data1参数,就要写value = 111, data1 = "111",且前面value也要写全
        String data1();

        //如果有default默认值,可以不写这参数,也能加上data2 = "222"修改参数
        String data2() default "222";
}


@TestAnnotation(value = 111,data1 = "111")
private int num1;

@TestAnnotation(value = 111,data1 = "111",data2 = "333")
private int num2;

5.注解使用

5.1 过时标记
  • 过时标记“ @Deprecated”,是Java自带的,这个注解标记过的,都会划上横线,就是不推荐在使用了


    过时
5.2 语法检查
  • 语法检查注解“@IntDef”,限制了参数类型,可以用来替代枚举类型
  • Android中还有很多 @DrawableRes、@IdRes、@StringRes、@AnimRes等等,后面带上“Res”就是限制传入的参数类型了
public class WeekDay {
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;

    //有效期在源码阶段,用于语法校验
    @Retention(RetentionPolicy.SOURCE)
    //该注解修饰属性、修饰方法参数
    @Target({ElementType.FIELD, ElementType.PARAMETER})
    //传入的类型只能是这几个
    @IntDef({MONDAY, TUESDAY, WEDNESDAY})
    public @interface WeekDayAnnotation {

    }
}
  • 我们可以看到写 1,会报错,提示只能传的类型
语法检查
5.3 findViewById
  • 不需要重复写findViewById,直接给控件加上注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView {
    @IdRes int value();
}
 
/*--------------------------------------------------------*/
 
 
public class InjectViewUtils {
    public static void injectView(Activity activity) {
        Class<? extends Activity> clazz = activity.getClass();
 
        //获取成员
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //判断是否被打上了InjectView注解标签
            if (field.isAnnotationPresent(InjectView.class)) {
                InjectView injectView = field.getAnnotation(InjectView.class);
                //获取View的id
                int id = injectView.value();
                View view = activity.findViewById(id);
 
                //反射设置值
                //设置权限,允许修改private的属性
                field.setAccessible(true);
                try {
                    field.set(activity,view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 使用
@InjectView(R.id.tvTest)
private TextView tvTest;

@InjectView(R.id.tvTest2)
private TextView tvTest2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    InjectViewUtils.injectView(this);
}
5.4 View的Onclick
  • 不需要拿到View,也不用写View的Onclick监听,直接加注解,省事
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectOnClick {
   @IdRes int[]  value();
}
 
/*------------------------------------------------------*/
 
/**
 * 点击事件处理
 */
public class OnClickUtils {
    static public void inject(final Activity activity) {
        Class<? extends Activity> clazz = activity.getClass();
 
        //获取所有方法
        Method[] methods = clazz.getDeclaredMethods();
        for (final Method method : methods) {
            //判断方法的注解类型
            if (method.isAnnotationPresent(InjectOnClick.class)) {
                InjectOnClick injectOnClick = method.getAnnotation(InjectOnClick.class);
                //获取id参数数组
                int[] ids = injectOnClick.value();
 
                //设置权限,可以修改private
                method.setAccessible(true);
                for (int id : ids) {
                    //每个id都设置
                    activity.findViewById(id).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            //调用方法回传
                            try {
                                method.invoke(activity);
                            } catch (Exception e) {
                                e.printStackTrace();
                                try {
                                    method.invoke(activity, v);
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            }
                        }
                    });
                }
            }
        }
    }
}
  • 使用
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    OnClickUtils.inject(this);
}

@InjectOnClick({R.id.tvTest, R.id.tvTest2})
private void OnClick(View view) {
    int id = view.getId();
    if (id == R.id.tvTest) {

    } else if (id == R.id.tvTest2) {

    }
}

6.结尾

  • 注解使用简单,但经常需要配合反射技术,后续有学习更多注解知识,就分享给大家。

相关文章

网友评论

    本文标题:Android 开发也要掌握的Java知识 - Java注解

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