Kotlin Symbol Processing(KSP)使用初体验
近日,android官方发布了Kotlin Symbol Processing(KSP)的alpha版本。
Announcing Kotlin Symbol Processing (KSP) Alpha
为什么使用KSP?
很多人在使用Kotlin时的痛点之一就是编译速度过慢。
很多常见的三方库都通过注解简化模板代码,例如Room、Dagger、Retrofit等,
Kotlin使用KAPT处理注解,KAPT没有专门的注解处理器,需要借助APT实现的,因为APT只能处理Java,所以KAPT需要生成APT可以解析的stub(Java代码),这影响了KAPT的性能,从而拖慢了Kotlin项目整体编译速度:
KSP正是在这个背景下诞生的,它基于Kotlin Compiler Plugin实现,随着Kotlinc的过程同步处理注解,不需要生成stub代码,编译速度是KAPT的2倍以上
KSP 与 Kotlin Compiler Plugin
Kotlin提供了编译器插件Compiler Plugin,可以在编译期分析AST、修改字节码产物等,Kotlin很多语法关键字以及注解都是基于KotlinCompilerPlugin实现的,例如data class
、@Parcelize
、kotlin-android-extension
等。
理论上Kotlin Compiler Plugin可以完全替代APT、transform等编译期工具,且效率更高,但是KCP的API学习成本高,需要了解一些编译器底层知识,普通开发者很难直接基于KCP处理注解。
一个的Compiler Plugin的开发需要若干过程:
KSP 的出现了屏蔽了对KCP了解,可以像使用KAPT一样,更愉快地进行注解处理
KSP使用初体验
SymbolProcessor
一般需要继承SymbolProcessor
来创建自己的KSP
interface SymbolProcessor {fun init(options: Map<String, String>,kotlinVersion: KotlinVersion,codeGenerator: CodeGenerator,logger: KSPLogger)fun process(resolver: Resolver) // Let's focus on thisfun finish()
}
然后通过访问者模式,处理AST:
class HelloFunctionFinderProcessor : SymbolProcessor() {...val functions = mutableListOf<String>()val visitor = FindFunctionsVisitor()override fun process(resolver: Resolver) {resolver.getAllFiles().map { it.accept(visitor, Unit) }}inner class FindFunctionsVisitor : KSVisitorVoid() {override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {classDeclaration.getDeclaredFunctions().map { it.accept(this, Unit) }}override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {functions.add(function)}override fun visitFile(file: KSFile, data: Unit) {file.declarations.map { it.accept(this, Unit) }}}...
}
Samples
举几个例子展示一下KSP中的API是如何使用的
- 访问类中的所有成员方法
fun KSClassDeclaration.getDeclaredFunctions(): List<KSFunctionDeclaration> {return this.declarations.filterIsInstance<KSFunctionDeclaration>()
}
- 判断一个类或者方法是否是局部类或局部方法
fun KSDeclaration.isLocal(): Boolean {return this.parentDeclaration != null && this.parentDeclaration !is KSClassDeclaration
}
- 判断一个类成员是否对其他Declaration可见
fun KSDeclaration.isVisibleFrom(other: KSDeclaration): Boolean {return when {// locals are limited to lexical scopethis.isLocal() -> this.parentDeclaration == other// file visibility or memberthis.isPrivate() -> {this.parentDeclaration == other.parentDeclaration|| this.parentDeclaration == other|| (this.parentDeclaration == null&& other.parentDeclaration == null&& this.containingFile == other.containingFile)}this.isPublic() -> truethis.isInternal() && other.containingFile != null && this.containingFile != null -> trueelse -> false}
}
- 解析注解
// Find out suppressed names in a file annotation:
// @file:kotlin.Suppress("Example1", "Example2")
fun KSFile.suppressedNames(): List<String> {val ignoredNames = mutableListOf<String>()annotations.forEach {if (it.shortName.asString() == "Suppress" && it.annotationType.resolve()?.declaration?.qualifiedName?.asString() == "kotlin.Suppress") {it.arguments.forEach {(it.value as List<String>).forEach { ignoredNames.add(it) }}}}return ignoredNames
}
使用KSP替代KAPT
KSP的目标很明确:开发者可以用近似KAPT的API处理注解,得到2倍以上的性能提升;使用者可以方便的将KAPT替换为KSP:
目前,已有不少三方库被要求增加对KSP的支持,并提上日程,相信随着KSP版本的逐渐稳定,未来这个趋势会越发明显。
Library | Status | Tracking issue for KSP |
---|---|---|
Room | In progress | Link |
Moshi | Experimentally supported | |
Auto Factory | Not yet supported | Link |
Dagger | Not yet supported | Link |
Hilt | Not yet supported | Link |
Glide | Not yet supported | Link |
如果你的项目也有对KAPT的需求,不妨试试KSP?
KSP :https://github.com/google/ksp
Kotlin Symbol Processing(KSP)使用初体验相关推荐
- 使用Kotlin开发Android应用初体验
使用Kotlin开发Android应用初体验 昨晚,最近一届的谷歌IO大会正式将Kotlin确定为了官方开发语言,作为一名Android开发鸟,怎么能不及时尝尝鲜呢? Kotlin的简要介绍 在开发之 ...
- Kotlin系列之Kotlin初体验
这一篇我们开始Kotlin代码之旅,一步步入门Kotlin. 一.Kotlin开发工具 Kotlin语言在开发之初,它的语言和插件工具是同步开发的. 这里推荐IntelliJ IDEA15及以上,ID ...
- MapReduce编程初体验
需求:在给定的文本文件中统计输出每一个单词出现的总次数 第一步: 准备一个aaa.txt文本文档 第二步: 在文本文档中随便写入一些测试数据,这里我写入的是 hello,world,hadoop he ...
- 树莓派2代B model 上手初体验,不用显示器,Python GPIO 点亮一颗LED
开题:[好东西,值得研究!] 标题:树莓派2代B model 上手初体验,不用显示器,Python GPIO 点亮一颗LED [知识普及] 1,树莓派各版本对比: 2,树莓派2代BModel 主板,图 ...
- Polygon zkEVM的pil-stark Fibonacci状态机初体验
1. 引言 前序博客: Polygon zkEVM 基本概念 第5章 "一个例子--Fibonacci state machine" 实操主要见: 2022年8月8日Jordi B ...
- 【你好Resilience4j】一:Resilience4j之初体验
每日一句 健身和读书,是世界上成本最低的升值方式:而懒,是你通往牛逼的路上最大的敌人. 目录 为什么要使用Resilience4j Resilience4j介绍 Resilience4j模块 初体验 ...
- 【ChatGPT初体验与Android的集成使用】
ChatGPT初体验与Android的集成使用 前言 创建自己的API KEY Android端的集成 代码 总结 前言 ChatGPT凭借着强大的AI功能火的一塌糊涂,由于其官网在国内不能访问,很多 ...
- 三、Hadoop系统应用之Hadoop集群测试及初体验(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)
Hadoop集群搭建前安装准备参考: 一.Hadoop系统应用之安装准备(一)(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7) 一.Ha ...
- Rasa课程、Rasa培训、Rasa面试系列之:Rasa 3.x部署安装初体验
Rasa课程.Rasa培训.Rasa面试系列之:Rasa 3.x部署安装初体验 Rasa 3.x部署安装 进入Ananconda系统,新建rasa虚拟环境 conda create --name in ...
最新文章
- Win32下内存分配简单示例 - 使用CFree
- C#中的默认访问修饰符
- Response_案例1_重定向_特点
- ASP.NET WEBAPI设计(文摘)
- Git标签tag及tag远程同步
- linux下远程登录如何退出,Ubuntu 中rdesktop如何切换和退出远程桌面
- Java游戏触屏处理,非触屏java游戏转换为触屏游戏工具使用方法
- Java设计模式学习总结(15)——行为型模式之责任链模式
- 计算机仿真电路实验感想,电路计算机仿真 实验报告.doc
- c语言引用与指针有什么区别,Java引用与C语言指针的区别
- Js时间相关处理函数
- Qt对图像的二值化处理
- JPA语法大全 特别是JPA的不等于
- IAP程序升级(全网最全)
- 开机出现recovering journal解决办法
- 初识C语言----完结篇
- Windows下安装ES
- Java 遍历map(Java8)
- 第3章 软件测试过程
- mysql select后面能跟多少个表_mysql查询语句中,FROM后面可以跟具体的表名,也可以跟一个查询结果...
热门文章
- 文献 | fMRI入门指南
- Cloudera Manager环境搭建【二】
- Loadrunner11 录制手机App脚本多种方法介绍
- 查看虚拟机vmware下linux的ip
- oracle rman crosscheck,rman crosscheck作用
- springboot中Error creating bean with name ‘keyExpiredListener‘ defined in f
- ws2812C驱动示例主控芯片为HC32F460系列
- OTA线下攻防战 | 一点财经
- 抖音名字怎么改不了_抖音名字怎么改,抖音名字改不了,抖音名字已重置什么意思...
- 使用Cloudflare Workers部署博客