Android APT 系列 (三):APT 技术探究

APT 介绍

什么是 APT ?

APT 全称 Annotation Processing Tool,翻译过来即注解处理器。引用官方一段对 APT 的介绍:APT 是一种处理注释的工具, 它对源代码文件进行检测找出其中的注解,并使用注解进行额外的处理。
APT 有什么用?

APT 能在编译期根据编译阶段注解,给我们自动生成代码,简化使用。很多流行框架都使用到了APT技术,如 ButterKnife,Retrofit,Arouter,EventBus 等等
APT 工程
1)、APT 工程创建

一般情况下,APT 大致的的一个实现过程:
1、创建一个Java Module ,用来编写注解
2、创建一个Java Module,用来读取注解信息,并根据指定规则,生成相应的类文件
3、创建一个Android Module ,通过反射获取生成的类,进行合理的封装,提供给上层调用
如下图:
在这里插入图片描述这是我的 APT工程,关于 Module名称可以任意取,按照我上面说的规则去进行就好了

2)、Module 依赖

工程创建好后,我们就需要理清楚各个 Module 之间的一个依赖关系:

1、因为 apt-processor 要读取apt-annotation的注解,所以apt-processor需要依赖apt-annotation

//apt-processor 的 build.gradle 文件
dependencies {
   
    implementation project(path: ':apt-annotation')
}

2、app 作为调用层,以上 3 个 Module都需要进行依赖

//app 的 build.gradle 文件
dependencies {
   
    //...
    implementation project(path: ':apt-api')
    implementation project(path: ':apt-annotation')
    annotationProcessor project(path: ':apt-processor')
}

APT工程配置好之后,我们就可以对各个 Module 进行一个具体代码的编写了
apt-annotation 注解编写

这个 Module的处理相对来说很简单,就是编写相应的自定义注解就好了,我编写的如下:

@Inherited
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({
   ElementType.TYPE,ElementType.METHOD})
public @interface AptAnnotation {
   
    String desc() default "";
}

apt-processor 自动生成代码

这个 Module 相对来说比较复杂,我们把它分为以下 3 个步骤:
1、注解处理器声明
2、注解处理器注册
3、注解处理器生成类文件
1)、注解处理器声明

1、新建一个类,类名按照自己的喜好取,继承javax.annotation.processing这个包下的 AbstractProcessor类并实现其抽象方法

public class AptAnnotationProcessor extends AbstractProcessor {
   
  
    /**
     * 编写生成 Java 类的相关逻辑
     *
     * @param set              支持处理的注解集合
     * @param roundEnvironment 通过该对象查找指定注解下的节点信息
     * @return true: 表示注解已处理,后续注解处理器无需再处理它们;false: 表示注解未处理,可能要求后续注解处理器处理
     */
    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
   
        return false;
    }
}

重点看下第一个参数中的 TypeElement ,这个就涉及到Element 的知识,我们简单的介绍一下:
Element 介绍
实际上,Java 源文件是一种结构体语言,源代码的每一个部分都对应了一个特定类型的 Element,例如包,类,字段,方法等等:

package com.dream;         // PackageElement:包元素

public class Main<T> {
        // TypeElement:类元素; 其中 <T> 属于 TypeParameterElement 泛型元素

    private int x;         // VariableElement:变量、枚举、方法参数元素

    public Main() {
           // ExecuteableElement:构造函数、方法元素
    }
}

Java 的 Element是一个接口,源码如下:

public interface Element extends javax.lang.model.AnnotatedConstruct {
   
    // 获取元素的类型,实际的对象类型
    TypeMirror asType();
    // 获取Element的类型,判断是哪种Element
    ElementKind getKind();
    // 获取修饰符,如public static final等关键字
    Set<Modifier> getModifiers();
    // 获取类名
    Name getSimpleName();
    // 返回包含该节点的父节点,与getEnclosedElements()方法相反
    Element getEnclosingElement();
    // 返回该节点下直接包含的子节点,例如包节点下包含的类节点
    List<? extends Element> getEnclosedElements();

    @Override
    boolean equals(Object obj);
  
    @Override
    int hashCode();
  
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉亭下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值