Android APO 注解处理解释器
相关文章:
Android AOP注解Annotation详解(一)
Android AOP之注解处理解释器详解(二)
Android AOP 注解详解及简单使用实例(三)
一、提取Annotation信息
当开发者使用了Annotation修饰了类、方法、Field等成员之后,这些Annotation不会自己生效,必须由开发者提供相应的代码来提取并处理Annotation信息。这些处理提取和处理Annotation的代码统称为APT(Annotation Processing Tool)。
JDK主要提供了两个类,来完成Annotation的提取:
- Java.lang.annotation.Annotation接口:这个接口是所有Annotation类型的父接口。
- java.lang.reflect.AnnotatedElement接口:该接口代表程序中可以被注解的程序元素。
1.1 Annotation接口
这个接口比较少用,这个接口里面有四个方法:
package java.lang.annotation; public interface Annotation { boolean equals(Object obj); int hashCode(); String toString(); //返回该注解的Class,元素使用了多个注解的时候,可以进行输出判断 Class<? extends Annotation> annotationType(); }
1.2 AnnotatedElement接口
该接口最常用的方法是isAnnotationPresent()、getAnnotation(Class annotationClass):
package java.lang.reflect; import java.lang.annotation.Annotation; public interface AnnotatedElement { //判断此元素上是否存在指定类型的注解,如果存在则返回true,否则返回false default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return getAnnotation(annotationClass) != null; } //返回此元素上存在的指定类型的注解,如果该类型的注解不存在,则返回null <T extends Annotation> T getAnnotation(Class<T> annotationClass); //返回此元素上存在的所有注解。 Annotation[] getAnnotations(); //返回此元素上存在的所有注解。不包括继承 Annotation[] getDeclaredAnnotations(); default <T extends Annotation> Annotation getDeclaredAnnotation(Class<T> annotationClass) { return AnnotatedElements.getDeclaredAnnotation(this, annotationClass); } default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { return AnnotatedElements.getDeclaredAnnotationsByType(this, annotationClass); } default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { return AnnotatedElements.getAnnotationsByType(this, annotationClass); } }
二、栗子One
简单获取方法
2.1 定义注解MyTag
@Target(ElementType.METHOD) //修饰方法 @Retention(RetentionPolicy.RUNTIME) //运行时可以获取 public @interface MyTag { }
2.2 定义解析器
public class MyTagParser { public static void process(Object clazz) { try { for (Method method : clazz.getClass().getMethods()) { if (method.isAnnotationPresent(MyTag.class)) { //获取到了,输出 Log.e("tag","被mytag注解修饰的方法:" + method.getName()); } else { Log.e("tag","没有被mytag注解修饰的方法:" + method.getName()); } } } catch (Exception en) { en.printStackTrace(); } } }
2.3 启动Activity
public class MainActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //调用解析器 MyTagParser.process(this); } @MyTag public void testYes(){ } public void testNo(){ } }
2.4 结果
运行就会看到输出,表示已经获取到了对应的实例
...... 02-18 15:23:41.622 12446-12446/? E/tag: 没有被mytag注解修饰的方法:stopServiceAsUser 02-18 15:23:41.622 12446-12446/? E/tag: 没有被mytag注解修饰的方法:takeKeyEvents 02-18 15:23:41.622 12446-12446/? E/tag: 没有被mytag注解修饰的方法:testNo 02-18 15:23:41.622 12446-12446/? E/tag: 被mytag注解修饰的方法:testYes 02-18 15:23:41.632 12446-12446/? E/tag: 没有被mytag注解修饰的方法:toString 02-18 15:23:41.632 12446-12446/? E/tag: 没有被mytag注解修饰的方法:triggerSearch 02-18 15:23:41.632 12446-12446/? E/tag: 没有被mytag注解修饰的方法:unbindService .......
三、栗子Two
取到方法里面的值
3.1 定义注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyTag { String name() default "天平"; int age(); }
3.2 定义解析器
public class MyTagParser { public static void parser(Object o){ Class clazz = o.getClass(); for(Method method:clazz.getMethods()){ if(method.isAnnotationPresent(MyTag.class)){ MyTag myTag = method.getAnnotation(MyTag.class); Log.e("tag","方法名:"+method.getName()+"的注解值为"+myTag.name()+","+myTag.age()); } } } }
3.3 定义activity
public class MainActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyTagParser.parser(this); } @MyTag(age = 20) public void testYes(){ } }
3.3 结果
将会输出以下内容,name和age都可以获取到。
02-18 16:11:53.493 25662-25662/? E/tag: 方法名:testYes的注解值为天平,20
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!