1. 创建AnnotationProject
2. 增加注解compile module
必须java Library
2.1 自定义注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS) public @interface MyAnnotation { String name(); }
2.2 定义注解处理器
@AutoService(Processor.class) public class MyAnnotationProcessor extends AbstractProcessor{ Filer mFiler; Messager mMessager; @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); mMessager = processingEnv.getMessager(); mFiler = processingEnv.getFiler(); } @Override public Set<String> getSupportedAnnotationTypes() { Set<String> annoation = new LinkedHashSet<>(); annoation.add(MyAnnotation.class.getCanonicalName()); return annoation; } @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { if (set == null || set.isEmpty()) { info(">>elements is null<<"); return true; } Set<?extends Element> elements = roundEnv.getElementsAnnotatedWith(MyAnnotation.class); if (elements == null || elements.isEmpty()) { info(">>> elements is null... <<<"); return true; } for (Element annotationElement:elements) { if (annotationElement.getKind() != ElementKind.CLASS) { error(annotationElement, "Only classes can be annotated with @%s", MyAnnotation.class.getSimpleName()); return true; } analysisAnnoation(annotationElement); } return false; } private void analysisAnnoation(Element classElement) { MyAnnotation annotation = classElement.getAnnotation(MyAnnotation.class); String name = annotation.name(); String newClassName = name; StringBuilder builder = new StringBuilder(); builder.append("package com.xxxx.annotation;\n\n") .append("public class ") .append(newClassName) .append("{\n\n") .append("\tpublic String getMessage() {\n") .append("\t\treturn \"") .append(name) .append("!\\n") .append("\";\n") .append("\t}\n") .append("}\n"); try { JavaFileObject source = mFiler.createSourceFile(newClassName); Writer write = source.openWriter(); write.write(builder.toString()); write.flush(); write.close(); } catch (IOException e) { e.printStackTrace(); } } private void info(String msg, Object... args) { mMessager.printMessage(Diagnostic.Kind.NOTE, String.format(msg, args)); } private void error(Element e, String msg, Object... args) { mMessager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e); } }
@AutoService 注册自定义注解处理器
gradle增加依赖
apply plugin: 'java-library' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.google.auto.service:auto-service:1.0-rc2' } sourceCompatibility = "1.7" targetCompatibility = "1.7"
3. 使用
配置gradle
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.pax.annotationprocessor"
minSdkVersion 22
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath = true
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(":compile")
}
增加注解
@MyAnnotation(name = "MyAnn") public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); com.xxxx.annotation.MyAnn myAnn = new MyAnn(); Log.i("TAG", myAnn.getMessage()); } }
运行app时报错如下:
Failed to find byte code for javax/annotation/processing/AbstractProcessor
处理方法:
File/Settings/Build/Instant Run