Android AOP之注解处理解释器详解(二)
AndroidAPO注解处理解释器
相关文章:
AndroidAOP注解Annotation详解(一)
AndroidAOP之注解处理解释器详解(二)
AndroidAOP注解详解及简单使用实例(三)
一、提取Annotation信息
当开发者使用了Annotation修饰了类、方法、Field等成员之后,这些Annotation不会自己生效,必须由开发者提供相应的代码来提取并处理Annotation信息。这些处理提取和处理Annotation的代码统称为APT(AnnotationProcessingTool)。
JDK主要提供了两个类,来完成Annotation的提取:
- Java.lang.annotation.Annotation接口:这个接口是所有Annotation类型的父接口。
- java.lang.reflect.AnnotatedElement接口:该接口代表程序中可以被注解的程序元素。
1.1Annotation接口
这个接口比较少用,这个接口里面有四个方法:
packagejava.lang.annotation;
publicinterfaceAnnotation{
booleanequals(Objectobj);
inthashCode();
StringtoString();
//返回该注解的Class,元素使用了多个注解的时候,可以进行输出判断
ClassannotationType();
}
1.2AnnotatedElement接口
该接口最常用的方法是isAnnotationPresent()、getAnnotation(ClassannotationClass):
packagejava.lang.reflect;
importjava.lang.annotation.Annotation;
publicinterfaceAnnotatedElement{
//判断此元素上是否存在指定类型的注解,如果存在则返回true,否则返回false
defaultbooleanisAnnotationPresent(ClassannotationClass){
returngetAnnotation(annotationClass)!=null;
}
//返回此元素上存在的指定类型的注解,如果该类型的注解不存在,则返回null
TgetAnnotation(ClassannotationClass);
//返回此元素上存在的所有注解。
Annotation[]getAnnotations();
//返回此元素上存在的所有注解。不包括继承
Annotation[]getDeclaredAnnotations();
defaultAnnotationgetDeclaredAnnotation(ClassannotationClass){
returnAnnotatedElements.getDeclaredAnnotation(this,annotationClass);
}
defaultT[]getDeclaredAnnotationsByType(ClassannotationClass){
returnAnnotatedElements.getDeclaredAnnotationsByType(this,annotationClass);
}
defaultT[]getAnnotationsByType(ClassannotationClass){
returnAnnotatedElements.getAnnotationsByType(this,annotationClass);
}
}
二、栗子One
简单获取方法
2.1定义注解MyTag
@Target(ElementType.METHOD)//修饰方法
@Retention(RetentionPolicy.RUNTIME)//运行时可以获取
public@interfaceMyTag{
}
2.2定义解析器
publicclassMyTagParser{
publicstaticvoidprocess(Objectclazz){
try{
for(Methodmethod:clazz.getClass().getMethods()){
if(method.isAnnotationPresent(MyTag.class)){
//获取到了,输出
Log.e("tag","被mytag注解修饰的方法:"+method.getName());
}else{
Log.e("tag","没有被mytag注解修饰的方法:"+method.getName());
}
}
}catch(Exceptionen){
en.printStackTrace();
}
}
}
2.3启动Activity
publicclassMainActivityextendsActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//调用解析器
MyTagParser.process(this);
}
@MyTag
publicvoidtestYes(){
}
publicvoidtestNo(){
}
}
2.4结果
运行就会看到输出,表示已经获取到了对应的实例
...... 02-1815:23:41.62212446-12446/?E/tag:没有被mytag注解修饰的方法:stopServiceAsUser 02-1815:23:41.62212446-12446/?E/tag:没有被mytag注解修饰的方法:takeKeyEvents 02-1815:23:41.62212446-12446/?E/tag:没有被mytag注解修饰的方法:testNo 02-1815:23:41.62212446-12446/?E/tag:被mytag注解修饰的方法:testYes 02-1815:23:41.63212446-12446/?E/tag:没有被mytag注解修饰的方法:toString 02-1815:23:41.63212446-12446/?E/tag:没有被mytag注解修饰的方法:triggerSearch 02-1815:23:41.63212446-12446/?E/tag:没有被mytag注解修饰的方法:unbindService .......
三、栗子Two
取到方法里面的值
3.1定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceMyTag{
Stringname()default"天平";
intage();
}
3.2定义解析器
publicclassMyTagParser{
publicstaticvoidparser(Objecto){
Classclazz=o.getClass();
for(Methodmethod:clazz.getMethods()){
if(method.isAnnotationPresent(MyTag.class)){
MyTagmyTag=method.getAnnotation(MyTag.class);
Log.e("tag","方法名:"+method.getName()+"的注解值为"+myTag.name()+","+myTag.age());
}
}
}
}
3.3定义activity
publicclassMainActivityextendsActivity{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTagParser.parser(this);
}
@MyTag(age=20)
publicvoidtestYes(){
}
}
3.3结果
将会输出以下内容,name和age都可以获取到。
02-1816:11:53.49325662-25662/?E/tag:方法名:testYes的注解值为天平,20
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!