Android Compile-time Annotation-APT Technology

Keywords: Java Google Gradle

APT(Annotation Processing Tool), or Annotation Processing Tool, is a tool for processing annotations. To be exact, it is a tool for javac to scan and process annotations at compile time. The annotation processor takes Java code (or compiled bytecode) as input and generates. java files as output.
Simply put, at compile time, annotations are used to generate. java files.

Runtime annotations (@Retention (Retention Policy.RUNTIME)): Runtime annotations, as mentioned earlier, are annotations that are captured and parsed when a program is running, and are reflected to achieve results after some information is obtained. Examples of runtime annotations.

Compile-time annotations (@Retention (Retention Policy. CLASS)): Compile-time annotations need to use proxy mode when compiling, generate corresponding Java files, use the java files when the program runs, and invoke methods to achieve the desired results.

Let's step by step implement APT:

1. Create annotation classes:

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

2. Create the AbstractProcessor implementation class:

@AutoService(Processor.class)
public class BindViewProcessor extends AbstractProcessor {

    private Messager mMessager;
    private Elements mElementUtils;
    private Map<String, ClassCreatorProxy> mProxyMap = new HashMap<>();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mMessager = processingEnv.getMessager();
        mElementUtils = processingEnv.getElementUtils();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        HashSet<String> supportTypes = new LinkedHashSet<>();
        /*** Here is to add the annotation class used to the collection ***/
        supportTypes.add(BindView.class.getCanonicalName());
        return supportTypes;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        /*** This is mainly to generate the required Java files, so this is the key place ***/
        ...
        return true;
    }

The three methods of init, getSupported Annotation Types and getSupported Source Version are fixed. The key point is the process method, which needs to be used to create Java class files. A third-party library, JavaPoet, can be used.

So when does the method of AbstractProcessor implementation class execute? SPI technology needs to be applied at this time. Notice that the BindViewProcessor class has an annotation @AutoService(Processor.class), a third-party library of google that needs to be referenced in gradle:

implementation 'com.google.auto.service:auto-service:1.0-rc2'

But sometimes it doesn't work, and I don't know why...

So the most stable way is to create the relevant folders by hand:

The content of javax.annotation.processing.Processor is the AbstractProcessor implementation class: the path of the BindViewProcessor class:

com.zy.apt_processor.BindViewProcessor

Posted by Pintonite on Wed, 07 Aug 2019 03:17:46 -0700