Android中注解处理器系列之-简单使用

概念

APT(Annotation Processing Tool)即注解处理器,是一种处理Java源代码的工具。它可以在编译期对注解进行处理,从而生成一些额外的代码或者进行一些额外的操作。相比于运行期注解处理,APT可以更加高效地处理注解,因为它是在编译期进行处理的。

在Android开发中,APT技术常常用于自动生成代码,比如生成View的findViewById方法、生成Activity的Intent参数传递代码、生成注入框架等。通过APT技术,可以大大提高代码的开发效率和可读性。常用的APT框架有ButterKnife、Dagger、EventBus等。
APT 在 Java 编译器完成第一次编译后,对生成的 Java 文件进行再次编译和处理,可以生成新的 Java 代码和资源文件,或者生成其他需要的文件,如配置文件、HTML、XML 等。

APT 的处理时机是在 Java 源代码编译时。在编译 Java 代码时,编译器会检查源代码中是否包含注解,并且会扫描所有注解处理器类,并执行这些注解处理器类中的 process() 方法,从而生成新的 Java 代码或者其他文件。由于 APT 的处理时机是在 Java 源代码编译时,因此需要在编译器中进行相关配置,以便在编译时调用注解处理器。通常需要在构建工具中进行配置,例如在 Gradle 中使用 apt 插件。

创建模块

首先我们创建两个java项目(注意必须为两个java模块,我之前因为创建模块错误,导致代码功能根本跑不通),分别为为compiler与annotations,其中annotations为自定义注解模块,compiler为助力器处理代码模块。

模块结构

创建依赖关系

app依赖:

implementation project(path: ':annotations')
//注意此处的依赖关键词
annotationProcessor  project(path: ':compiler')

compiler依赖:

//这里用到了spi机制
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4'
compileOnly 'com.google.auto.service:auto-service:1.0-rc4'

implementation project(path: ':annotations')

创建process类(注解处理节点)

注意我们最终工作的地方就是以下process的方法内,在此方法中我们可以生成我们想生成的文件,并通过JavaWriter将文件写到本地,其实写文件就是拼接字符串的过程。

注意此类文件是在compiler中创建的

/**
 * 注解处理器,用来生成代码的
 * 使用前需要注册
 * 此代码是在电脑中执行的。
 */
@AutoService(Processor.class)
public class AnnotationsCompiler extends AbstractProcessor {
    //1.支持的版本
    @Override
    public SourceVersion getSupportedSourceVersion() {
        //选择最新的版本
        return SourceVersion.latestSupported();
    }

    //2.能用来处理哪些注解。
    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> types = new HashSet<>();
        types.add(BindView.class.getCanonicalName());
        return types;
    }

    //3.定义一个用来生成APT目录下面的文件的对象
    Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        filer = processingEnvironment.getFiler();
    }


    /**
     * 在这个方法中生成文件。
     *
     * @param set
     * @param roundEnvironment
     * @return
     */
    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {


        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,"test-------------"+set);
        //获取APP中所有用到了BindView注解的对象
        Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(BindView.class);

//        TypeElement//类
//        ExecutableElement//方法
//          VariableElement//属性
        //开始对elementsAnnotatedWith进行分类
        Map<String, List<VariableElement>> map = new HashMap<>();
        for (Element element : elementsAnnotatedWith) {
            VariableElement variableElement = (VariableElement) element;
            String activityName = variableElement.getEnclosingElement().getSimpleName().toString();
            Class aClass = variableElement.getEnclosingElement().getClass();
            List<VariableElement> variableElements = map.get(activityName);
            if (variableElements == null) {
                variableElements = new ArrayList<>();
                map.put(activityName, variableElements);
            }
            variableElements.add(variableElement);
        }
     


        return false;
    }
}

创建注解

这里在annotations中随便创建了一个注解,用来调试用。(如果注解的使用方法不会用的建议网上搜索相关知识来学习)。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface BindView {
    int value();
}

测试使用

在测试Activity中使用注解注释TextView。

public class MainActivity extends AppCompatActivity {
    //注解
    @BindView(R.id.main_tv)
    TextView textView;
}

点击as,进行构建工程,我们可以在build中看见我们打印的日志信息。

test-------------[com.example.annotation.BindView]

目前此文章知识讲解apt的简单入门使用。
后面讲解apt的实践以及源码解读。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陈德山

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

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

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

打赏作者

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

抵扣说明:

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

余额充值