android 自定义注解处理器
作用:
注解处理器就是将注解生成对应的java类,生成java类可以使用javaPoet。
如何自定义注解处理器呢?有以下步骤:
1、我们创建一个module,名字为testProcessor,注意它是一个java library;如果是一个java library,在testProcessorx下的build.gradle中第一行是apply plugin: 'java-library',但是这个插件只有在gradle 4才支持,修改方式:file--->project structure--->Project---->gradle version 将版本改成4.1
2、创建一个注解类,这个类必须继承自AbstractProcessor,如下所示:
public class TestProcessor extends AbstractProcessor
其实注解类和我们的Activity一样也需要注册,但是我们可以使用google自带的工具auto-service,testProcessor中的build.gradle代码如下:
apply plugin: 'java-library' //引入的插件,需要将gradle版本修改到4以上dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.google.auto.service:auto-service:1.0-rc2' //引入auto-service实现注解自动注册 implementation 'com.squareup:javapoet:1.7.0' //使用开源框架javapoet生成Java类}sourceCompatibility = "1.7" //指定java兼容版本targetCompatibility = "1.7"
同时我们需要注解类上添加一些注解,代码如下:
@AutoService(Processor.class) //使用此注解自动注册,//当前注解处理器能够处理的注解 代替 getSupportedAnnotationTypes函数@SupportedAnnotationTypes({"com.example.administrator.apt.Route"})//定义注解处理器需要处理注解的类型//java版本 代替 getSupportedAnnotationTypes 函数@SupportedSourceVersion(SourceVersion.RELEASE_7) //指定jdk的版本public class TestProcessor extends AbstractProcessor {
这就是注解器注册的位置,然后文件中的内容就是我们注解器的全类名,如com.example.testprocessor.TestProcessor
然后在app中的build.gradle中引用此注解:
annotationProcessor project(':testProcessor')
3、重写注解器的init方法和process方法,代码如下:
/** * Created by Administrator on 2018/3/21. */@AutoService(Processor.class)//当前注解处理器能够处理的注解 代替 getSupportedAnnotationTypes函数@SupportedAnnotationTypes({"com.example.administrator.apt.Route"})//java版本 代替 getSupportedAnnotationTypes 函数@SupportedSourceVersion(SourceVersion.RELEASE_7)public class TestProcessor extends AbstractProcessor { private Messager messager; Filer filer; @Override public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment); filer = processingEnvironment.getFiler(); messager = processingEnvironment.getMessager();//获取信息打印工具 messager.printMessage(Diagnostic.Kind.NOTE, "TestProcessor=============init");//打印信息,在Gradle Console可以看到打印信息,如果第一个参数写成Kind.ERROR将会信息中断 } @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) { messager.printMessage(Diagnostic.Kind.NOTE, "TestProcessor=============process"); for (TypeElement typeElement : set) {//set集合都是注解节点,但是我们要拿到的是被注解的节点 MethodSpec main = MethodSpec.methodBuilder("main")//创建方法 .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(void.class) .addParameter(String[].class, "args") .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") .build(); TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")//创建类 .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addMethod(main) .build(); JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld) .build();//创建文件 try { javaFile.writeTo(filer); } catch (IOException e) { e.printStackTrace(); } } return false; }}
以上process方法中的for中的作用就是生成java类,java文件,此文件存放app--build---generated---source--apt如下所示;
4、如果需要传递参数,我们可以在app的build.gradle中的defaultConfig中配置一下代码:
javaCompileOptions { annotationProcessorOptions { arguments = [moduleName: project.getName()] } }
同时在TestlProcessor之上添加一个注解
/** * 处理器接收的参数 替代 {@link AbstractProcessor#getSupportedOptions()} 函数 */@SupportedOptions("moduleName")
更多相关文章
- app包下的fragment 和 v4 包下的fragment的区别 以及兼容包suppo
- Mac下Android(安卓)Studio 使用git版本控制个人心得
- Android(安卓)AOP之AspectJ入门
- 关于无论怎么切换NDK的版本都出现 NDK_PROJECT_PATH = null(特例)
- Unable to resolve target 'android-i'
- Android(安卓)studio安装:
- Myeclipse出现错误:Errors running builder 'Android(安卓)Packag
- AndroidStudio opencv(一)
- Android(安卓)studio 命令gradlew assembleRelease打包时,出现 Un