什么是注解加反射?
思路:
1.我们需要自定义一个注解(标签)
2.在我们需要的类中运用这个注解(在需要的地方运用标签)
3.在方法中去循环遍历类中的属性或者方法(去找标签,根据自己的需求去实现想要的东西)
例子:
1.@ViewById 用来替代findViewById(),避免代码的冗余
代码的实现:
(1)注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById {
int value();
}
(2)标签实现的功能
public static void findViewById(Activity activity){
Class <?> clazz = activity.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields ){
ViewById viewById = field.getAnnotation(ViewById.class);
if (viewById!=null){
int viewId = viewById.value();
View view = activity.findViewById(viewId);
try {
//两个参数 1.该属性在哪个对象里面 2.给属性设置的值
field.setAccessible(true);
field.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
(3)运用地方
@ViewById(R.id.textview)
TextView textView;
textView.setText("哈哈");
2.@OnClick 用来代替setOnClickListener(),避免代码的冗余
代码的实现:
(1)注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value();
}
(2)标签实现的功能
private static void onClick(final Activity activity) {
Class<?> clazz = activity.getClass();
Method[] methods = clazz.getDeclaredMethods();
for (final Method method:methods){
OnClick onClick = method.getAnnotation(OnClick.class);
if (onClick!=null){
int [] viewIds = onClick.value();
for (int viewId :viewIds){
View view = activity.findViewById(viewId);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
method.setAccessible(true);
try {
method.invoke(activity);//无参的方法
} catch (Exception e) {
try {
method.invoke(activity,v);//有参的方法 v代表当前点击的view对象
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
});
}
}
}
}
(3)运用地方
@OnClick(R.id.btn)
private void btnClick(Button btn){
Toast.makeText(this,btn.getText().toString(),Toast.LENGTH_SHORT).show();
}
3.我们在运用别人的注解时,不难发现会有这么个东西
初始化,放在静态类中,程序只会运行一次
inject(this);
去实现调用其他方法 public static void inject(Activity activity){
findViewById(activity);
onClick(activity);
}
5.效果
1.声明注解主要两个东西:@Target(目标,作用域)和 @Retention(元注解:在什么时候用)
2.对于私有的方法,属性。我们要setAccessible()
7.思考:我用过Annotation这个注解框架
这个注解,和我们用的注解加反射不一样,好像用的是生成继承类的方法,在Build.grade还用到了插件apt,我还得研究研究~~