Android APT从入门到实战

8 篇文章 2 订阅
订阅专栏

APT(Annotation Processing Tool)即注解处理器,在编译的时候可以处理注解然后搞一些事情,也可以在编译时生成一些文件之类的。ButterKnife和EventBus都使用了APT技术,如果不会APT技术就很难看懂这两个框架的源码。

tempImage1629265217303.jpeg

  • 实现效果

我们来实现一个简单的功能,只要在任何类的成员变量上添加一个 @Print注解,就可以动态生成一个方法,然后把成员变量的变量名输出:

10.png

动态生成的类大概长这样:

11.png

  • 整理思路

  1. 首先我们需要创建两个JavaLibrary
  2. 一个用来定义注解,一个用来扫描注解
  3. 获取到添加注解的成员变量名
  4. 动态生成类和方法用IO生成文件
  • 实战

  • 创建一个空项目

1.png

  • 创建两个JavaLibrary

  1. 注解的Lib: apt-annotation
  2. 扫描注解的Lib: apt-processor

2.png

3.png

  • 创建完之后

4.png

  • app模块依赖两个Library

implementation project(path: ':apt-annotation')
annotationProcessor project(path: ':apt-processor')

8.png

  • 注解Lib中创建一个注解类

如果还不会自定义注解的同学,可以先去看我之前写的一篇 Java自定义注解入门到实战

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface Print {

}

12.png

  • 扫描注解的Lib添加依赖

dependencies {
    //自动注册,动态生成 META-INF/...文件
    implementation 'com.google.auto.service:auto-service:1.0-rc6'
    annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'
    //依赖apt-annotation
    implementation project(path: ':apt-annotation')
}

6.png

  • 创建扫描注解的类

7.png

  • 重写init方法,输出Hello,APT

注意: 这里是JavaLib,所以不能使用Log打印,这里可以使用Java的println()或注解处理器给我们提供的方法,建议使用注解处理器给我们提供的

13.png

  • 见证奇迹

现在我们已经完成了APT的基本配置,现在我们可以build一下项目了,成败在此一举

14.png

  • 踩坑指南

  1. 如果你已经成功输出了文本,说明APT已经配置好,可以继续下一步了
  2. 如果你失败了:
  1. 如果继承的时候找不到AbstractProcessor类,那你 创建的肯定不是JavaLibrary,你可以删掉重新创建
  2. 如果点击编译没反应,你可以试试先 clear一下项目再重新编译
  3. 如果都不行,就去检查一下前面流程的 依赖是否都配置正确
  • 继续完成功能

现在我们可以继续完成上面要实现的功能了,我们需要先来实现几个方法

/**
 * 要扫描扫描的注解,可以添加多个
 */
@Override
public Set<String> getSupportedAnnotationTypes() {
    HashSet<String> hashSet = new HashSet<>();
    hashSet.add(Print.class.getCanonicalName());
    return hashSet;
}

/**
 * 编译版本,固定写法就可以
 */
@Override
public SourceVersion getSupportedSourceVersion() {
    return processingEnv.getSourceVersion();
}

15.png

  • 定义注解

我们先在MianActivity中添加两个成员变量并使用我们定义的注解

17.png

  • 定义注解

真正解析注解的地方是在process方法,我们先试试能不能拿到被注解的变量名

/**
 * 扫描注解回调
 */
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    //拿到所有添加Print注解的成员变量
    Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Print.class);
    for (Element element : elements) {
        //拿到成员变量名
        Name simpleName = element.getSimpleName();
        //输出成员变量名
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,simpleName);
    }
    return false;
}

18.png

  • 编译试一下

19.png

  • 生成类

既然能拿到被注解的变量名,后面就简单了,我们只需要用字符串拼出来一个工具类,然后用IO流写到本地就ok了

20.png

  • 查看效果

现在点击一下编译,然后我们可以看到app模块下的build文件已经有我们生成的类了

21.png

  • 调用方法

现在我们回到MainActivity,就可以直接调用这个动态生成的类了

9.png

tempImage1629273861493.gif

  • 实战结束

结束了吗…好像是结束了,但是上面拼接类的方法感觉一不小心就会写错,有没有更好的方法呢,我们先来看看EventBus的源码是怎么生成的:

23.png
看到大佬也是这样拼接的,这我就放心了🤡,我们再看一下ButterKnife的源码是怎么生成的:

24.png
ButterKnife的源码竟然不是用字符串拼接的!!! 隐约看到TypeSpec.classBuilder,这是啥玩意?不过身为资深的程序猿这点问题我们还是可以很容易的找到答案的

25.png

  • JavaPoet

经过一个小时的百度,大概研究了一下JavaPoet,这玩意好像可以帮我们以面向对象的思维来生成类,这样我们就不用手动拼接字符串的方式来生成类了,那我们来优化一下上面的代码:

先添加依赖
implementation 'com.squareup:javapoet:1.13.0'

29.png

/**
 * 扫描注解回调
 */
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    //拿到所有添加Print注解的成员变量
    Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Print.class);

    //生成类
    TypeSpec.Builder classBuilder = TypeSpec
            .classBuilder("PrintUtil")
            .addModifiers(Modifier.PUBLIC, Modifier.FINAL);

    for (Element element : elements) {
        //拿到成员变量名
        Name simpleName = element.getSimpleName();
        //生成方法
        MethodSpec method = MethodSpec.methodBuilder("print$$"+simpleName)
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .returns(void.class)
                .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
                .build();
        classBuilder.addMethod(method);
    }
    //包
    JavaFile javaFile = JavaFile
            .builder("com.lkx.helloapt", classBuilder.build())
            .build();
    try {
        javaFile.writeTo(processingEnv.getFiler());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

27.png

  • 编译一下

28.png

tempImage1629276608514.jpeg

  • 总结

  1. APT可以在编译器扫描注解帮我们提前生成类
  2. JavaPoet可以帮我们优雅的生成类,再也不用拼接了
  3. APT最主要的功能就是可以替代反射的一些功能,避免降低性能
  4. APT只会在编译时影响一点点速度,在运行期不会,而反射刚好相反
Android APT
zenmela2011的专栏
08-01 1067
1.APT注解处理器 APT是Annotation Processing Tool 的简称,即注解处理器。它是一种处理注解的工具,可以在代码编译期扫描并解析注解,最终生成处理注解逻辑的Java文件,从而减少手动的代码输入。ButterKnife、EventBus、ARouter、GreenDAO都使用了APT技术。 使用APT可以在编译时来处理编译时注解,生成额外的Java文件,有如下效果: ①可以达到减少重复代码手工编写的效果。如ButterKnife,可以直接使用注解来减少findviewb.
Android组件化实战四: APT的介绍与使用
天亮了的博客
06-18 2001
前言 上一篇文章分析了组件化模块交互的两种实现方式,对于全局Map保存目标Activity的路径信息和类对象方案,如果Activity的数量繁多,则需要在主模块app的application中重复执行多次保存操作,既不优雅,又不符合实际开发场景,我们想到的解决之一就是想办法生成一个来完成这个重复枯燥的任务,生成一个类来帮我们找到跳转目标Activity的class对象。好比Butterknife生成一个文件专门完成findViewById的操作一样。这就涉及到注解处理器即apt技术,接下来就了解apt的使用
Android APT 系列 (二):APT 筑基之注解
工宗浩生财指南针
06-26 402
元数据元数据就是为其他数据提供信息的数据注解官方解释:注解用于为代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 JDK 1.5 开始添加到 Java 的。简单的理解:注解就是附加到代码上的一种额外补充信息注解作用源码阶段注解: 编译器可利用该阶段注解检测错误,提示警告信息,打印日志等编译阶段注解:利用注解信息自动生成代码、文档或者做其它相应的自动处理运行阶段注解: 可通过反射获取注解信息,做相应操作如何自定义定义一个注解。
Android 解耦(三)基于 APT 的解耦
夏夏的博客
08-03 201
init:初始化注解处理器,获取一些工具类对象,如 Elements、Types、Filer 等getSupportedAnnotationTypes:返回支持处理的注解类型集合,如 Service、Method、Param 等process:处理标记了支持的注解类型的元素(Element),并根据规则生成相应的中间类例如:// 自定义注解处理器 public class ServiceProcessor extends AbstractProcessor {
AndroidAPT
tran_sient的博客
01-01 633
本文介绍了Android中的一种技术:APT
Android APT 系列 (三):APT 技术探究
工宗浩生财指南针
06-26 827
什么是 APT?APT 全称 Annotation Processing Tool,翻译过来即注解处理器。引用官方一段对 APT 的介绍:APT 是一种处理注释的工具, 它对源代码文件进行检测找出其中的注解,并使用注解进行额外的处理。APT 有什么用?APT 能在编译期根据编译阶段注解,给我们自动生成代码,简化使用。很多流行框架都使用到了APT技术,如 ButterKnife,Retrofit,Arouter,EventBus 等等APT 工程1)、APT 工程创建。
Android Apt之Activity Route的示例
08-28
本篇文章主要介绍了Android Apt之Activity Route的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
解决Android studio 2.3升级到Android studio 3.0 后apt报错问题
08-28
原来项目在Android studio 2.3一切正常,升级到了3.0之后报错,不支持apt了,其实解决这个问题很简单,只需要修改两点内容就可以,下面脚本之家小编带领大家通过本文学习吧
Android-AndroidAPT编译时代码生成最佳实践
08-13
Android APT(编译时代码生成)最佳实践
Android APT 快速教程
LiMubai_CN的博客
10-19 1199
Android APT快速教程 简介 APT(Annotation Processing Tool)即注解处理器,是一种用来处理注解的工具。JVM会在编译期就运行APT去扫描处理代码中的注解然后输出java文件。 简单来说~~就是你只需要添加注解,APT就可以帮你生成需要的代码 许多的Android开源库都使用了APT技术,如ButterKnife、ARouter、EventBus等 动手实现一...
如何在 Android 中完成一个 APT 项目的开发?
hdbdhdbh的博客
10-11 121
APT(Annotation Processing Tool)即注解处理器,是一种处理注解的工具。APT在编译时期扫描处理源代码中的注解,开发中可以根据注解,利用APT自动生成Java代码,减少冗余的代码和手动的代码输入过程,提升了编码效率,同时使源代码看起来更清晰简洁,可读性提升。目前,很多第三方开源框架采用APT技术,以减少开发者的重复工作。常见的如ButterKnife、EventBus等。
提高10倍开发效率?APT如何让Android开发变得更轻松
嘴巴吃糖了
03-11 903
Android开发中,APT(Annotation Processing Tool)是一种强大的工具,它可以让开发者在编译期间处理注解,生成额外的代码。通过APT,我们可以实现很多高级功能,比如自动生成代码、实现依赖注入、生成路由表等。本文将深入探讨APT的运用以及背后的原理。首先定义一个注解@BindView在这里使用了@Target和@Retention两个重要的元注解,用来对注解进行定义和修饰。通过本文的介绍,相信大家已经对APT有了更深入的理解,并且能够在实际的项目中运用APT来提高开发效率。
Android APT技术学习
cat_is_so_cute的博客
12-27 2170
Android APT技术简单说明,仿照Butterknife实现了View的自动绑定demo
APT技术在Android中的使用
renzhongrui的博客
11-07 4060
APT技术在Android中的使用 APT全称 Annotation Process Tool,是Java提供的注解处理工具,能够帮助开发者在编译阶段生成所需要的可执行代码。 在Android开发中,著名的ButterKnife、Dagger2、ARouter都是使用了APT技术,所以作为一名Android开发者,还是有必要了解一下APT技术的使用。 Android中使用APTAndroid工程中使用APT,首先需要创建两个Java Module,一个是annotation(注解module,也可以是A
Android APT及基于APT的简单应用
weixin_34409357的博客
08-13 401
前言:随着一些如ButterKnife,dagger等的开源注解框架的流行,APT的概念也越来越被熟知。这篇文章将介绍APT的概念,以及我们怎么利用APT来自定义一个注解。 一,APT的介绍   APT英文全称:Android annotation process tool是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,使用Annotation进行额外的处理。   An...
Android studio添加apt
小小侠
08-18 909
第一步添加 classpath 第二步 添加apply plugin 第三步 添加apt
android studio apt配置,Android studio 中 想导入androidannotation 的配置问题。
weixin_34966346的博客
05-27 241
(一) Project 的 build.gradlebuildscript{repositories{jcenter()}dependencies{classpath'com.android.tools.build:gradle:1.2.3'classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'//NOTE:Donot...
JavaPoet动态生成代码,21年Android面经分享
最新发布
2401_83620865的博客
03-17 121
定义一个注解处理器,需要继承自AbstractProcessor。12345678910111213141516171234567891011121314151617init(ProcessingEnvironment env): 每一个注解处理器类都必须有一个空的构造函数。然而,这里有一个特殊的init()方法,它会被注解处理工具调用,并输入ProcessingEnviroment参数。
Android 安装 apt
06-01
Android 平台上安装 apt 工具需要进行如下步骤: 1. 在 Android 终端上安装 Termux 应用,可以在 Google Play 上下载安装。 2. 打开 Termux 应用,执行以下命令更新软件包: ``` apt update && apt upgrade ``...

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • Android 签名后安装失败(-103) 15670
  • Android自定义属性 Error: Found item Attr/font more than one time Error 6760
  • Android 百度地图导航没有声音的解决方法 6450
  • Android 通知栏Notification点击跳转无效 6363
  • Android APT从入门到实战 6125

分类专栏

  • 笔记 1篇
  • Android 8篇
  • Java进阶 7篇
  • Java基础 3篇
  • kotlin 1篇
  • 小程序 5篇

最新评论

  • Android HandlerThread源码解析

    人生几何-: 面试官:我就问一个问题,应用场景在哪?

  • Android APT从入门到实战

    咖喱给给的徐小黑: 写的太好了!!!爱爱爱爱爱爱爱爱死

  • Android APT从入门到实战

    life_2: 谢谢!!!!!!!!

  • Android APT从入门到实战

    beinn: 感谢手把手教学表情包

  • Android APT从入门到实战

    leach-chen: 写的挺详细

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • Android IntentService源码解析
  • Android HandlerThread源码解析
  • Android Handler源码浅析
2021年15篇
2020年1篇
2019年6篇
2018年6篇
2017年35篇
2016年1篇

目录

目录

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

聚圣源甜心战士五代史伶官传序走光露毛家装十大品牌起名希四个字建筑工程公司起名大全英勇无畏的成语免费铺店起名带睿字起名的妾倾城主烤官自助烧烤加盟房地产小区起名大全韩国护肤品哪个牌子好起小孩的名字姓李网上八字取名起名大全君临起名软件公司起名名字慧心妙舌起名带飞公司正能量满满的励志句子高端化妆品起名字李云迪王力宏热吻心田上的百合花关起名字免费音乐下载网站猪小孩张姓起名大全东北大米起名自你离开以后猪年宝宝起名适宜用字浠字起名寓意淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化