Annotation Processor在Android下的应用
1. 新建一个Java Library(processor),注意这一步是必须的,否则无法导入某些java的注解类,估计是Android 的限制。
build.gradle配置如下:
applyplugin:'java'
dependencies {
compile fileTree(dir:'libs',include: ['*.jar'])
}
sourceCompatibility ="1.8"
targetCompatibility ="1.8"
2. 编写Annotation声明类HelloAnnotation.java
packageorg.penguin.study.annotationprocessor.processor;
/**
* Created by terry on 12/07/2017.
*/
public @interface HelloAnnotation {
}
3. 编写对应Annotation的处理类HelloAnnotationProcessor.java
packageorg.penguin.study.annotationprocessor.processor;
importjava.io.IOException;
importjava.io.Writer;
importjava.util.Set;
importjavax.annotation.processing.AbstractProcessor;
importjavax.annotation.processing.RoundEnvironment;
importjavax.annotation.processing.SupportedAnnotationTypes;
importjavax.annotation.processing.SupportedSourceVersion;
importjavax.lang.model.SourceVersion;
importjavax.lang.model.element.Element;
importjavax.lang.model.element.TypeElement;
importjavax.tools.JavaFileObject;
@SupportedAnnotationTypes("org.penguin.study.annotationprocessor.processor.HelloAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class HelloAnnotationProcessorextendsAbstractProcessor {
@Override
public boolean process(Set annotations,RoundEnvironment roundEnv) {
StringBuilder builder =newStringBuilder()
.append("package org.penguin.study.annotationprocessor.generated;\n\n")
.append("public class GeneratedClass {\n\n").append("\tpublic String getMessage() {\n")
.append("\t\treturn\"");
// for each javax.lang.model.element.Element annotated with the CustomAnnotation
for(Element element : roundEnv.getElementsAnnotatedWith(HelloAnnotation.class)) {
String objectType = element.getSimpleName().toString();
// this is appending to the return statement
builder.append(objectType).append(" Java Annotation Process 入门经典!\\n");
}
builder.append("\";\n")
.append("\t}\n")
.append("}\n");
try{
JavaFileObject source =processingEnv.getFiler().createSourceFile("org.penguin.study.annotationprocessor.generated.GeneratedClass");
Writer writer = source.openWriter();
writer.write(builder.toString());
writer.flush();
writer.close();
}catch(IOException e) {
// 此处的IO异常一般发生在第一次编译的时候,基本不用处理。
}
return true;
}
}
4. 在Java Library(processor)下创建目录resources
5. 在Java Library(processor)下resources目录下创建目录META-INF下创建目录services
6. 在Java Library(processor)下resources/META-INF/services目录下创建文件javax.annotation.processing.Processor
7. 在Java Library(processor)下resources/META-INF/services/javax.annotation.processing.Processor文件中标明Annotation处理类
org.penguin.study.annotationprocessor.processor.HelloAnnotationProcessor
8. 在Android app module或其它module中引入依赖的 processor module:compile project(path:':processor'),然后就可以使用注解He'llAnnotation了
packageorg.penguin.study.android;
importandroid.os.Bundle;
importandroid.support.v7.app.AppCompatActivity;
importandroid.widget.TextView;
importorg.penguin.study.annotationprocessor.generated.GeneratedClass;
importorg.penguin.study.annotationprocessor.processor.HelloAnnotation;
importbutterknife.BindView;
importbutterknife.ButterKnife;
@HelloAnnotation
public classMainActivityextendsAppCompatActivity {
@BindView(R.id.txtMessage)
TextViewtxtMessage;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
GeneratedClass generatedClass =newGeneratedClass();
txtMessage.setText(generatedClass.getMessage());
}
}
9. app module的build.gradle内容如下:
applyplugin:'com.android.application'
android {
compileSdkVersion26
buildToolsVersion"26.0.0"
defaultConfig {
applicationId"org.penguin.study.android"
minSdkVersion19
targetSdkVersion26
versionCode1
versionName"1.0"
testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"
jackOptions {
enabledtrue
}
}
buildTypes {
release {
minifyEnabledfalse
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibilityJavaVersion.VERSION_1_8
targetCompatibilityJavaVersion.VERSION_1_8
}
packagingOptions {
exclude'META-INF/ASL2.0'
exclude'META-INF/LICENSE'
exclude'META-INF/license.txt'
exclude'META-INF/NOTICE'
exclude'META-INF/notice.txt'
}
}
dependencies {
compile fileTree(dir:'libs',include: ['*.jar'])
compile'com.android.support:appcompat-v7:26.+'
compile'com.android.support.constraint:constraint-layout:1.0.2'
compile'com.jakewharton:butterknife:8.7.0'
annotationProcessor'com.jakewharton:butterknife-compiler:8.7.0'
compile project(path:':processor')
testCompile'junit:junit:4.12'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
excludegroup:'com.android.support',module:'support-annotations'
})
}
经过上面的配置,一个demo就可以跑起来了,生成的java源码app/build/generated/source/apt/debug/org/penguin/study/annotationprocessor/generated/GeneratedClass.java
package org.penguin.study.annotationprocessor.generated;
public class GeneratedClass {
public String getMessage() {
return "MainActivity Java Annotation Process 入门经典!\n";
}
}