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 AbstractProcessorSpecify 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