Custom annotations (1)

Annotation is a feature introduced by JDK1.5, which is used to explain the code. It can mark packages, classes, interfaces, fields, method parameters, local variables, etc. into three categories: 1. The standard annotations that come with
java
, Such as @Override (overriding a method), @Deprecated (indicating that a class or method is obsolete), @SuppressWarnings (indicating warnings to be ignored)
2. One type is meta-annotations, which are used to define annotations for annotations, including @Retention (indicating the stage where the annotation is retained), @Target (indicating the scope of the annotation), @Inherited (indicating that the annotation can be inherited), @Documented (indicating whether to generate javadoc documents) 3. Custom annotations can be customized according to your
needs Definition Annotation

Function:
1. Generate documents, generate javadoc documents through the metadata identified in the code
2. Compile inspection, let the compiler check and verify during compilation through the metadata identified in the code
3. Dynamic processing at compile time, pass the code at compile time Dynamic processing of the metadata represented in the code, such as dynamically generating code
4. Dynamic processing at runtime, dynamic processing of the metadata represented in the code at runtime, such as using reflection injection instance

Android's custom annotations
use meta-annotations to define our custom annotations

meta annotation illustrate
@Target Indicates where our annotations can appear. is an ElementType enumeration
@Retention The lifetime of this annotation
@Document Indicates that annotations can be documented by tools such as javadoc
@Inherited Whether to allow subclasses to inherit the annotation, the default is false

@Target ElementType type description:
ElementType.TYPE interface, class, enumeration, annotation
ElementType.FIELD field
ElementType.METHOD method
ElementType.PARAMETER method parameter
ElementType.CONSTRUCTOR constructor
ElementType.LOCAL_VARIABLE local variable
ElementType.ANNOTATION_TYPE annotation
ElementType.PACKAGE package

@Retention RetentionPolicy type description:
The RetentionPolicy.SOURCE annotation is only retained in the source file. When the Java file is compiled into a class file, the annotation is discarded. The
RetentionPolicy.CLASS annotation is retained in the class file, but it is discarded when the jvm loads the class file. This is The default life cycle
RetentionPolicy.RUNTIME annotation is not only saved in the class file, but still exists after jvm loads the class file

Declare annotations:
use the @Retention meta-annotation to determine the timing of our annotations, as above,
use @Target to determine what our annotations are applied to

Classification of custom annotations:
**Runtime annotations, **Find our custom annotations through the reflection mechanism during the code running process, and then do the corresponding things
**Compile-time annotations, **Use javac in the compilation process Annotation processor to scan to our custom annotations, process annotations to generate some files we need (usually java files)

Compile-time annotations:
1. Declaration annotations
2. Parsing annotations

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
    
    
    int value();
}

The analysis of annotations at compile time requires us to implement an annotation analysis processor ourselves. Pay attention to the work done by the processor, which is to find the annotations that specify us during the code compilation process, and then add your own specific logic (usually generate java files). Note: To
implement a module, it must be java-library (because java library can inherit Processor AbstractProcessor)
In order to facilitate our registration of annotation processors, goole provides a registered processor library @AutoService(Processor.class) for registration

add dependencies

dependencies {
    
    
    implementation 'com.google.auto.service:auto-service:1.0-rc2'
}
@AutoService(Process.class)
public class BindViewProcessor extends AbstractProcessor {
    
    
private Elements elements;
private Messager messager;
private Filer filer;
private Types types;

    /**
     * 注解处理器的核心方法,在这里来处理注解,并生成Java辅助类
     *
     * @param set
     * @param roundEnvironment
     * @return
     */
    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
    
    
	Set<? extends Element> annotationElements = 	roundEnvironment.getElementsAnnotatedWith(BindView.class);
	for (Element element : annotationElements){
    
    
    	//获取字段名称
   	 if (element instanceof TypeElement) {
    
    
        		//注解用于类
        		try {
    
    
            	TypeElement typeElement2 = (TypeElement) element;
           	 System.out.println("typeElement2:" + typeElement2);
       	 	} catch (Exception e) {
    
    
            	e.printStackTrace();
        		}
    	} else {
    
     //注解用于字段
    		}
	}
        return false;
    }

    /**
     * 编译期间,init()会自动被注解处理工具调用,并传入ProcessingEnvironment参数,
     * 通过该参数可以获取到很多有用的工具类(Elements,Filer,Messager等)
     */
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
    
    
        super.init(processingEnv);
		elements = processingEnv.getElementUtils();
		messager = processingEnv.getMessager();
		filer = processingEnv.getFiler();
		types = processingEnv.getTypeUtils();

    }

    /**
     * 返回processor可处理的注解
     *
     * @return
     */
    @Override
    public Set<String> getSupportedAnnotationTypes() {
    
    
        Set<String> sets = new HashSet<>();
        sets.add(BindView.class.getCanonicalName());
        return sets;
    }


    /**
     * 用于指定你的java版本,一般返回:SourceVersion.latestSupported()
     */
    @Override
    public SourceVersion getSupportedSourceVersion() {
    
    
        return super.getSupportedSourceVersion();
    }
}

The core of the process() method is the Element element, which represents the elements of the program. During annotation processing, the compiler scans all java source files and regards each part of the source code as a specific type of Element custom
processing In addition to understanding the Element class and other subclasses, the processor process also needs 4 helper classes:

Annotation processor helper class illustrate
Elements A tool class for processing Element
Types A utility class for handling TypeMirror
Filer Used to create files (such as creating java files)
Messenger For output, similar to the print function

These four helper classes can be obtained through ProcessingEnvironment in the init() function

After writing the annotation processor, import it in the app module

implementation project(":模块名称")

In the process function, the element with the given annotation can be returned through RoundEnvironment
Source code:

public interface RoundEnvironment {
    
     
    // 返回使用给定类型注解的元素。 
    Set<? extends Element> getElementsAnnotatedWith(TypeElement var1); 
    // 返回使用给定类型注解的元素。
    Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> var1);
}

Guess you like

Origin blog.csdn.net/qq_42447739/article/details/125983841