一种更为优雅的方案 Gradle 插件 + kotlinPoet 最先想到的一种简单且不失风度的解决方案就是这个了,与火山引擎的 mars-gradle-plugin 不同的是,**这个方案的插件需要在 buildSrc 的 build.gradle(.kts) 被 apply**,然后: 还是从 dependency-lock.json 里读取依赖信息 通过 kotlinPoet 在 buildSrc 的 kotlin 目录下生成 Dependency.kt 用 kotlinPoet 进行元编程之前,我期望生成的 Dependency.kt 能满足以下条件: Dependency 是一个单例 Dependency 其实就是有一天,突然翻到森哥的一篇是时候放弃 JavaPoet/KotlinPoet 了 ,内心 OS:你让我放弃就放弃啊,我不管,KotlinPoet 天下第一... 参考 https://www.volcengine.com/docs/6436/110098 是时候放弃 JavaPoet/KotlinPoet 了 | Johnson Lee https://touk.pl
利用注解解析器(APT)和代码生成器(kotlinpoet)可以根据注解在编译期间就生成相应的代码,业界称之为Router机制 一、Gradle配置及架构分层 在实现Router机制之前,我们还可以对项目的组织架构进行优化 可以获取到RouterMeta val RouterMetaByPath: LinkedHashMap<String, RouterMeta> = LinkedHashMap() } 四、APT+kotlinpoet 自动生成类 有了上面的接口和全局缓存,我们就需要自动生成两个实现类了 1.新建插件Module 2.配置Gradle 需要支持APT和kotlinpoet plugins { id 'java-library implementation group: 'com.squareup', name: 'kotlinpoet', version: '1.10.2' } 3.定义一些全局变量 APT解析节点和 使用APT获取Router注解的类,并进行包装,最后存入一个group-RouterMeta列表的Map中 对group-RouterMeta列表的Map进行处理,首先遍历RouterMeta列表,使用kotlinpoet
AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) annotation class AutoInject 我们添加 auto-service 和 kotlinpoet 代码生成器的依赖 implementation 'com.squareup:kotlinpoet:1.4.0' compileOnly "com.google.auto.service:auto-service kotlinpoet 是一个用于生成 Kotlin 代码的库,由 Square 公司开发。KotlinPoet 通过提供一个强大的 DSL(领域特定语言)来帮助开发者编程地构建 Kotlin 源文件。 两者经常被一起使用,尤其是在创建编译时注解处理器时,当你编写一个注解处理器来处理注解时,可能会用到 KotlinPoet 来生成一些 Kotlin 代码,同时用 AutoService 来注册注解处理器
维护成本变低(小黑可以财务室结账了)、效率更高、出错概率也更小了(新增需求只需要关注一个 Car 子类即可) 材料准备 自定义注解 Annotation Processor JavaPoet or KotlinPoet 特别注意如果使用 Kotlin 的话,要需要在build.gradle中加上 plugins { id 'kotlin-kapt' } // 或者 apply kapt 使用 JavaPoet or KotlinPoet 生成代码 JavaPoet 和 KotlinPoet 是一个生成 Java/Kotlin 代码的库 在上面的例子中,我们需要扫描出所有标注了 @CarAnnotation 注解的类,然后自动生成一个 cardList.forEach { sb.appendln("\"${it.first}\" -> return ${it.second}()") } sb.append("}") 3.用 KotlinPoet
要先编译,会在你的接口类的文件夹下生成一个xxxRepository.class ------------------------------------------ 这是通过注解自动生成的文件,使用了kotlinpoet isNeedReturnType,方法是否需要返回值 [1240] AutoFlowApiFuncBuilder 这个是AutoFlowApi注解最关键的方法了,里面代码比较多,但是也没什么好解释的,就是对kotlinpoet
getKotlinPluginVersion()}") implementation(project(":RouterAnnotation")) implementation("com.squareup:kotlinpoet com.kronos.router.RouterCallback" } } 这部分就比较简单了,先判断类型是Activity还是RouterCallbac,然后根据不同的类型,插入不同的注册代码,只是相对于以前来说,这次我选择了KotlinPoet
MutableSet<out TypeElement>, roundEnv: RoundEnvironment): Boolean { return true } } 三、动态生成字节码 使用kotlinpoet
fix: Correcting handling of super-classes/interfaces on anonymous classes https://github.com/square/kotlinpoet
javapoet还有kotlinpoet这两个都可以展开一篇文章了,这边就不过分展开了啊。
为了紧随时代的潮流,这次还是用kotlinpoet生成的kt代码,也碰到了一些奇奇怪怪的问题。比如kotlin的Map类并不是java的Map吗,kotlin的String也和java的完全不同。
build(); build.writeTo(filer); } 这里要提一下,现在越来越多的人使用Kotlin语言开发app,你甚至可以使用https://github.com/square/kotlinpoet
Dagger2、Glide以及Jetpack库里非常好用Room数据库框架,都使用到了APT,它能够在编译时检索注解信息,通过Javapoet框架生成Java类、方法等相关代码(想生成Kotlin相关代码,使用kotlinpoet