文章目录

  • AbstractProcessor
    • 方法详细信息
  • ProcessingEnvironment
    • 方法详细信息
  • 1 新建 Java Library
    • 1.1 新建
    • 1.2 确定依赖关系
  • 2 创建自定义注解
    • 2.1 添加注解:Route
    • 2.2 添加注解 :Extra
    • 2.3 使用注解
  • 3 注解处理器
    • 3.1 新建RouteProcessor
    • 3.2 注册注解处理器
    • 3.3 覆写方法
  • 4 Android注解处理器(APT)简单实例
  • 5 javapoet简单使用

Annotation Processor是javac的一个工具,它用来在编译时扫描和处理注解。通过Annotation Processor可以获取到注解和被注解对象的相关信息,然后根据注解自动生成Java代码,省去了手动编写,提高了编码效率。
图:编译器原理


AbstractProcessor

参考:http://www.matools.com/api/java8

旨在用作最具体注释 processor 的便捷超类的抽象注释 processor。此类检查注释值,以计算其子类型所支持的选项、注释和源版本。

在 processor 被初始化之后,获取方法可以使用可用设施来发出有关值得注意的条件的警告。

只要遵守该方法的常规 Processor 协定,子类可随意重写此类中任何方法的实现和规范。

方法详细信息

  • init:用处理环境初始化 processor,方法是将 processingEnv 字段设置为 processingEnv 参数的值。如果在同一对象上多次调用此方法,则抛出 IllegalStateException。参数:processingEnv - 用来访问工具框架提供给 processor 的设施的环境

  • getSupportedOptions:如果 processor 类是使用 SupportedOptions 注释的,则返回一个不可修改的集合,该集合具有与注释相同的字符串集。如果类不是以这种方式注释的,则返回一个空集合。

  • getSupportedAnnotationTypes:返回支持注释类型名称的set集合

  • getSupportedSourceVersion:返回注释中的源版本。

  • process:处理先前 round 产生的类型元素上的注释类型集,并返回这些注释是否由此 Processor 声明。如果返回 true,则这些注释已声明并且不要求后续 Processor 处理它们;如果返回 false,则这些注释未声明并且可能要求后续 Processor 处理它们。Processor 可能总是返回相同的 boolean 值,或者可能基于所选择的标准而返回不同的结果。
    如果 Processor 支持 “*” 并且根元素没有注释,则输入集合将为空。Processor 必须妥善处理空注释集。
    参数:annotations - 请求处理的注释类型;roundEnv - 有关当前和以前 round 的信息的环境
    返回:注释集是否由此 Processor 声明

  • getCompletions:返回一个空的 completion 迭代。
    参数:
    element - 将被注释的元素
    annotation - 将应用于元素的注释(可能是一部分)
    member - 为其返回可能 completion 的注释成员
    userText - 将补充完整的源代码文本

  • isInitialized
    如果此对象已被 初始化,则返回 true,否则返回 false。

ProcessingEnvironment

参考:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

注释处理工具框架将提供一个具有实现此接口的对象的注释 processor,因此 processor 可以使用该框架提供的设施来编写新文件、报告错误消息并查找其他实用工具。

第三方可能希望提供能包装此接口设施对象的增值包装器,例如,允许多个 processor 协同写出单个源文件的 Filer 扩展。为了实现这一点,对于在其副作用可通过 API 相互可见的上下文中运行的 processor,工具基础设施必须提供相应的设施对象,这些对象是 .equals、作为 .equals 的 Filer 等等。此外,必须能够配置工具调用,使得从运行注释 processor 的角度来看,至少已选定的帮助 (helper) 类子集可视为由相同的类加载器加载。(因为设施对象管理共享状态,所以包装器类的实现必须知道以前是否包装过相同的基本设施对象。)

方法详细信息

  • getOptions():返回传递给注释处理工具的特定于 processor 的选项。选项是以从选项名称到选项值的映射形式返回的。对于不包含任何值的选项,映射中的对应值为 null。
    关于如何传入特定于 processor 的选项的详细信息,请参阅特定工具基础设施的文档。例如,命令行实现可以通过使用已知字符串作为特定于 processor 的选项的前缀来区分它们;其他工具实现可能遵守不同的约定或提供替换机制。除了特定于 processor 的选项外,给定实现还可以提供特定于实现的方式来查找传递给该工具的选项。
    返回:传递给工具的特定于 processor 的选项

  • getMessager()
    返回用来报告错误、警报和其他通知的 Messager。
    返回:Messager

  • getFiler()
    返回用来创建新源、类或辅助文件的 Filer。
    返回:Filer

  • getElementUtils()
    返回用来在元素上进行操作的某些实用工具方法的实现。
    返回:元素实用工具

  • getTypeUtils()
    返回用来在类型上进行操作的某些实用工具方法的实现。
    返回:类型实用工具

  • getSourceVersion()
    返回任何生成的 源和 类文件应该符合的源版本。
    返回:生成的源和类文件应该符合的源版本

  • getLocale()
    返回当前语言环境;如果没有有效的语言环境,则返回 null。该语言环境可用来提供本地化的 消息。
    返回:当前语言环境;如果没有有效的语言环境,则返回 null


刚接触Annotation Processor的同学可能会遇到找不到AbstractProcessor类的问题,大概率是因为直接在Android项目里边引用了AbstractProcessor,然而由于Android平台是基于OpenJDK的,而OpenJDK中不包含Annotation Processor的相关代码。因此,在使用Annotation Processor时,必须在新建Module时选择Java Library,处理注解相关的代码都需要在Java Library模块下完成。我们需要看一下整个项目的结构

1 新建 Java Library

1.1 新建

新建两个 Java Library,在新建Module时选择下图:

名称分别为router_annotation和router_compiler(注解处理器),如下图:

1.2 确定依赖关系

在router_compiler中添加router_annotation为依赖库,如下图:

查看router_compiler的build.gradle文件,如下图:

2 创建自定义注解

在router_annotation中添加注解:

2.1 添加注解:Route

//添加元注解
// @Target(ElementType.TYPE)   //接口、类、枚举、注解
// @Target(ElementType.FIELD) //字段、枚举的常量
// @Target(ElementType.METHOD) //方法
// @Target(ElementType.PARAMETER) //方法参数
// @Target(ElementType.CONSTRUCTOR)  //构造函数
// @Target(ElementType.LOCAL_VARIABLE)//局部变量
// @Target(ElementType.ANNOTATION_TYPE)//注解
// @Target(ElementType.PACKAGE) ///包
@Target(ElementType.TYPE)
//注解的生命周期
//RetentionPolicy.SOURCE  源码阶段
//RetentionPolicy.CLASS   编译阶段
//RetentionPolicy.RUNTIME 运行阶段
@Retention(RetentionPolicy.CLASS)
public @interface Route {/***路由的路径,标识一个路由节点*/String path();//没有默认值/*** 将路由节点进行分组,可以实现按组动态加载*/String group() default "";//有默认值
}

因为String path()没有设置默认值,所有在使用Route注解的时候必须设置path的值。

2.2 添加注解 :Extra

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Extra {String name() default "";
}

2.3 使用注解

app中添加router_annotation依赖。

在MainActivity添加注解:

@Route(path="/main/mainactivity")//1
public class MainActivity extends AppCompatActivity {@Extra(name="path")private String path;
}

注释1:在Route中path没有默认值,所以必须设置path。


3 注解处理器

在router_compiler中:

3.1 新建RouteProcessor

在router_compiler中新建自定义注解处理器RouteProcessor:

public class RouteProcessor extends AbstractProcessor {@Overridepublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {return false;}
}

3.2 注册注解处理器

在这个类上添加了@AutoService注解,它的作用是用来生成META-INF/services/javax.annotation.processing.Processor文件的,也就是我们在使用注解处理器的时候需要手动添加META-INF/services/javax.annotation.processing.Processor,而有了@AutoService后它会自动帮我们生成。AutoService是Google开发的一个库,使用时需要在 factory-compiler中添加依赖。

在router_compiler的build.gradle中添加依赖,如下:

 annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'compileOnly 'com.google.auto.service:auto-service:1.0-rc6'

在RouteProcessor中注册注解处理器:

/*** 在这个类上添加了@AutoService注解,它的作用是用来生成* META-INF/services/javax.annotation.processing.Processor文件的,* 也就是我们在使用注解处理器的时候需要手动添加* META-INF/services/javax.annotation.processing.Processor,* 而有了@AutoService后它会自动帮我们生成。* AutoService是Google开发的一个库,使用时需要在* factory-compiler中添加依赖*/
@AutoService(Processor.class)   //注册注解处理器
public class RouteProcessor extends AbstractProcessor {}

Make Project后查看生产的文件,如下图:

打开查看如下:

自动生成了RouteProcessor的路径。

3.3 覆写方法

在RouteProcessor中覆写3个方法,如下:

@AutoService(Processor.class)   //注册注解处理器
public class RouteProcessor extends AbstractProcessor {@Overridepublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {return false;}@Overridepublic synchronized void init(ProcessingEnvironment processingEnvironment) {super.init(processingEnvironment);}@Overridepublic SourceVersion getSupportedSourceVersion() {return SourceVersion.RELEASE_7;}@Overridepublic Set<String> getSupportedAnnotationTypes() {return super.getSupportedAnnotationTypes();}
}

这里也可以通过注解的方式实现,如下:

@AutoService(Processor.class)   //注册注解处理器@SupportedOptions("moduleName")@SupportedSourceVersion(SourceVersion.RELEASE_7)@SupportedAnnotationTypes({"com.hongx.router_annotation.Route"})public class RouteProcessor extends AbstractProcessor {@Overridepublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {return false;}
}

4 Android注解处理器(APT)简单实例

Android注解处理器(APT)简单实例

5 javapoet简单使用

在上面使用了StringBuilder来构建类的,比较麻烦,我们可以使用javapoet简化构建类过程。

javapoet

Android 自定义注解处理器详解相关推荐

  1. Android 自定义注解处理器

    之前我们可能用过dagger.hilt之类的注解,使用这些注解可以方便我们的工作,减少我们的代码编写量.因此,本文主要是介绍如何自定义一个注解处理器.可以分为2个部分,一.定义注解和注解处理器:二.注 ...

  2. Android自定义View构造函数详解

    转自:http://blog.csdn.net/wzy_1988/article/details/49619773 目录 目录 初始Custom View的构造函数 生成Custom View的自定义 ...

  3. android标尺自定义view,android尺子的自定义view——RulerView详解

    项目中用到自定义尺子的样式: 原效果为 因为跟自己要使用的view稍有不同 所以做了一些修改,修改的注释都放在代码中了,特此记录一下. 首先是一个自定义View: public class RuleV ...

  4. Android中自定义注解处理器

    注解和注解生成器 如果没有处理注解的工具,那么注解也不会有太大的作用.对于不同的注解有不同的注解处理器.虽然注解处理器的编写千变万化,但是也有处理标准. 参考文献:https://blog.csdn. ...

  5. Java注解(Annotation)详解

    转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...

  6. Android 源码编译详解【合集篇】

    Android 源码编译详解[一]:服务器硬件配置及机型推荐 做 Android系统开发多年,开发环境都是入职就搭建好了,入职时拿个账号密码就直接开始搞开发了,年初换了新公司,所有的项目都是刚起步,一 ...

  7. SpringSecurity权限管理框架系列(六)-Spring Security框架自定义配置类详解(二)之authorizeRequests配置详解

    1.预置演示环境 这个演示环境继续沿用 SpringSecurit权限管理框架系列(五)-Spring Security框架自定义配置类详解(一)之formLogin配置详解的环境. 2.自定义配置类 ...

  8. 注解提高篇:自定义注解处理器(APT)

    ## 0x01 继承AbstractProcessor抽象类 当定义好Annotation注解后,接下来就需要一个注解处理器来处理我们的自定义注解了.实现Java Annotation一般需要继承Ab ...

  9. Android应用坐标系统全面详解

    Android应用坐标系统全面详解 原文链接:CSDN@工匠若水,http://blog.csdn.net/yanbober/article/details/50419117 1. 背景 去年有很多人 ...

最新文章

  1. SQL应用中级指南 Part4:(数据字典)
  2. linux之sed命令的用法
  3. Java源文件的编译、下载、解释和执行
  4. Client向Server send数据,返回WSAEWOULDBLOCK错误
  5. Sublime Text3前端必备插件
  6. Filter_细节_web.xml配置方式
  7. 简单使用TFS管理源代码
  8. 二、数据库设计与操作
  9. Qt QtCreator 所有版本官方下载地址
  10. 想成领袖?先瞄准老板身边的位置
  11. apk android lite,APKPure Lite
  12. Visual C# 2008+SQL Server 2005 数据库与网络开发――3.2.4 匿名类型
  13. springcloud服务调用以及整合Hystrix
  14. java 重定向关键字_springboot实现转发和重定向
  15. paper reading:Part-based Graph Convolutional Network for Action Recognition
  16. 11.抓取JavaScript
  17. js 设计模式(23种)
  18. 区分度评估指标-KS
  19. angular8.x + ngx-translate实现国际化
  20. 容抗 感抗 初级计算公式

热门文章

  1. mysql的设置参数中max_allowed_packet
  2. GreenPlum 大数据平台--运维(三)
  3. 常用的数据库统计SQL语句(2)
  4. 10G 82599EB 网卡测试优化 ethtool
  5. 一、<a>标签如何实现下载
  6. 搜狗有一个超良心的功能 Ctrl+shift+E
  7. IBM Cloud 2015 - Invoice - 03 payment 支付方式
  8. 人人视频显示服务器睡着了,人人视频显示连接超时
  9. 【开发教程9】疯壳·开源蓝牙心率防水运动手环-心率监测
  10. 爱思考CISP证书适合哪些人学习?