Annotation(注解)
如果想學(xué)習(xí)APT(注解處理工具)骏令,那么就必須先了解Annotation的基礎(chǔ)蔬捷,對于不了解java注解基礎(chǔ)的朋友們,請先學(xué)習(xí)java注解榔袋,再看本文周拐。
APT
APT(Annotation Processing Tool)是一種處理注釋的工具,它對源代碼文件進(jìn)行檢測找出其中的Annotation,使用Annotation進(jìn)行額外的處理凰兑。
Annotation處理器在處理Annotation時(shí)可以根據(jù)源文件中的Annotation生成額外的源文件和其它的文件(文件具體內(nèi)容由Annotation處理器的編寫者決定),APT還會編譯生成的源文件和原來的源文件妥粟,將它們一起生成class文件。
創(chuàng)建Annotation Module
android studio 現(xiàn)在是最主流的安卓開發(fā)工具吏够,而且也是最好用的勾给,所有我這里講的是apt在studio上的使用教程滩报。
首先,我們需要新建一個(gè)Java Library,用來定義注解锦秒,所以庫名最好為annotation,見名知意喉镰。注意旅择,庫一定要為Java Library,因?yàn)閍ndroid Library不會引入javax.annotation等包侣姆,新建java Library 的方式如下圖:
此庫的build.gradle如下:
可根據(jù)自己的需求生真,修改jdk版本。
創(chuàng)建apt Module
創(chuàng)建一個(gè)名為apt的Java Library捺宗,見名知意柱蟀,此庫是用來編寫如何處理注解的代碼,同時(shí)通過注解自動生成代碼蚜厉。
配置build.gradle
apply plugin: 'java'
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.auto.service:auto-service:1.0-rc2'
compile 'com.squareup:javapoet:1.7.0'
compile project(':annotation')
}
jdk同上庫
AutoService 主要的作用是注解 processor 類长已,自動生成。
JavaPoet 這個(gè)庫的主要作用就是幫助我們通過類調(diào)用的形式來生成代碼昼牛。
-
依賴上面創(chuàng)建的annotation Module术瓮。
到這里所有的配置都完了,接下來編寫代碼贰健。
定義注解
在annotation庫新建一個(gè)Test接口胞四,定義注解
```
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Test { }
```
定義Processor類
@AutoService(Processor.class)//自動生成 javax.annotation.processing.IProcessor 文件
@SupportedSourceVersion(SourceVersion.RELEASE_8)//java版本支持
@SupportedAnnotationTypes({"com.tuodao.annotation.Test"})//標(biāo)注注解處理器支持的注解類型,就是我們剛才定義的接口Test伶椿,可以寫入多個(gè)注解類型辜伟。
public class AnnotationProcessor extends AbstractProcessor {
public Messager mMessager;
public Elements mElements;
public Filer mFiler;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
mFiler = processingEnv.getFiler();//文件相關(guān)的輔助類
mElements = processingEnv.getElementUtils();//元素相關(guān)的輔助類
mMessager = processingEnv.getMessager();//日志相關(guān)的輔助類
MethodSpec methodMain = MethodSpec.methodBuilder("main")//創(chuàng)建main方法
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)//定義修飾符為 public static
.addJavadoc("@ 此類由apt自動生成")//在生成的代碼前添加注釋
.returns(void.class)//定義返回類型
.addParameter(String[].class, "args")//定義方法參數(shù)
.addStatement("$T.out.println($S)", System.class, "helloWorld")//定義方法體
.build();
TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")/創(chuàng)建HelloWorld類
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)//定義修飾符為 public final
.addMethod(methodMain)//添加方法
.addJavadoc("@ 此方法由apt自動生成")//定義方法參數(shù)
.build();
JavaFile javaFile = JavaFile.builder("com.tuodao.apt", helloWorld).build();// 生成源 代碼
try {
javaFile.writeTo(mAbstractProcessor.mFiler);//// 在 app module/build/generated/source/apt 生成一份源代碼
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
在App中使用
配置app的build.gradle
dependencies {
//..
compile project(':annotation')
annotationProcessor project(':apt')//核心,有了這個(gè)app才會處理apt的代碼
}
在隨意一個(gè)類添加@Test注解
@Test
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
然后編譯脊另,在app的build/generated/source/apt目錄下导狡,可看到生成的代碼
如下 :
/**
* @ 此方法由apt自動生成 */
public final class HelloWorld {
/**
* @ 此類由apt自動生成 */
public static void main(String[] args) {
System.out.println("helloWorld");
}
}
至此,一個(gè)簡單的HelloWorld就完成了