android studio annotation processing application

1.AbstractProcessor class introduction

On eclipse, you can use annotations to process efficient processing code, and it can also be used on Android studio.

javax.annotation.processing.AbstractProcessor

It is an abstract class located in the javax.annotation.processing package and has nothing to do with ide. by implementing

public abstract boolean process(Set<? extends TypeElement> annotations,
                                RoundEnvironment roundEnv)

Process the annotations marked on the source code.

2. Classification of annotations

According to function, annotations are divided into 3 categories:

a.@Retention(RetentionPolicy.SOURCE), does not need to be recorded in the class file

b.@Retention(RetentionPolicy.CLASS) , which needs to be recorded in the class file, but does not need to be retained during operation

c.@Retention(RetentionPolicy.RUNTIME) , which needs to be recorded in the class file and needs to be retained during operation

Class C can be called and processed by reflection at runtime, and it can be applied flexibly, but it needs to sacrifice a certain performance, and it cannot be confused to lose original information, which lacks security.

AbstractProcessor does not affect performance by processing annotations, and it can be completely obfuscated.

 

3.build.gradle configuration

In the module dependencies, add the provided annotation library (including all @interface classes), add the annotationProcessor annotation processing library (including the AbstractProcessor class)

A complete module build.gradle example

 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"


    defaultConfig {
        applicationId "cn.zhg.test.annotations"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 1
        versionName "0.9.0"


    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    provided project(':libannotations')
    annotationProcessor project(':processor')
}
 The project directory structure is

 


 

4. Annotation class library

Create a new libannotations java library module, such as creating an InjectParcel annotation here to automatically implement Parcel for entity classes,

 

package cn.zhg.test.annotations;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.CLASS)
@Target({  ElementType.TYPE})
public @interface InjectParcel
{
    /**
     * Specify the generated class name
     * @return
     */
    String value() default "";
}
 @Target({ ElementType.TYPE}) specifies that it can only be used on classes, @Retention(RetentionPolicy.CLASS) does not need to be used at runtime

 

5. Annotation processing class
@SupportedAnnotationTypes("cn.zhg.test.annotations.*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class TestInjectProcessor extends AbstractProcessor
 Specify the support version and annotation class, and get all the annotations that need to be processed in the process
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment)
    {
        log("Processing...");
        Set<? extends Element> annotations = roundEnvironment.getElementsAnnotatedWith(InjectParcel.class);
 Get information about the target class
TypeElement classElement = (TypeElement) it;
                    String packageName = elementUtils.getPackageOf(classElement).getQualifiedName().toString();//包名
                    String  className = classElement.getQualifiedName().toString();//全名
                    String  simpleName = classElement.getSimpleName().toString();//简名
                    String targetClassName=simpleName+"Parcel";//The name of the generated class
                    InjectParcel an = classElement.getAnnotation(InjectParcel.class);
                    if(!an.value().isEmpty())
                    {
                        targetClassName=an.value();
                    }
 Create source code through processingEnv.getFiler()#createSourceFile
JavaFileObject jfo = processingEnv.getFiler().createSourceFile(packageName+"."+targetClassName);
try( Writer writer = jfo.openWriter())
                       {
//Write the source code
}
 For each build, the source code will be generated at {ProjectDir}/{ModuleName}/build/generated/source/apt/{BuildVar} 6. End

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326121337&siteId=291194637