前言
注解最常见的用法就是去掉繁琐的findviewbyId方法,通过注解的方式绑定控件,代替findviewbyId和强制类型转换。能使代码更简洁。
@ViewInject(id = R.id.tx1)
private TextView textView;
@ViewInject(id = R.id.button)
private Button button;
下面介绍Android中注解的使用方法和原理。
定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewInject {
int id();
//int value();
}
@interface 表示定义一个注解,ViewInject为注解类的名称,内部包含一个int id(),也可以使用默认的value(),这里代表的是一个属性,并不是一个方法,属性的类型是int。
元注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
称为元注解。这里代表注解作用在域field,并且在runtime运行时有效。
常见的元注解如下:
(一)Target 注解作用目标1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
1.SOURCE:在源文件中有效
2.CLASS:在class文件中有效
3.RUNTIME:在运行时有效
具体使用注解代替findviewbyId的流程
(1) 定义注解
(2)注解关联解析工具
AnnotationUtil就是去遍历Activity中的目标域,通过反射的方式拿到Field,用getAnnotation方法判断是否有ViewInject的注解,当存在时拿到相应的属性也就是id,利用这个值给相应的域进行赋值,所以本质上还是需要调用findviewbyId这个方法。
public class AnnotationUtil {
public static void injectViews(Activity activity){
Class<? extends Activity> klass = activity.getClass();
Field[] fields = klass.getDeclaredFields();
for(Field field : fields){
ViewInject viewInject = field.getAnnotation(ViewInject.class);
if(viewInject != null){
try {
int id = viewInject.id();
field.setAccessible(true);
field.set(activity,activity.findViewById(id));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
(3)在activity中启用AnnotationUtil
AnnotationUtil.injectViews(this);
可以在activity的基类中调用,在setcontentView之前调用。
(4)在域中调用@injectView
@ViewInject(id = R.id.tx1)
private TextView textView;
注意注解不需要以分号结尾,如果注解的定义是用默认的value,则可以直接使用@ViewInject(R.id.tx1),否则需要使用@ViewInject(id = R.id.tx1)