近日,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@Parcelizekotlin-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)使用初体验相关推荐

  1. 使用Kotlin开发Android应用初体验

    使用Kotlin开发Android应用初体验 昨晚,最近一届的谷歌IO大会正式将Kotlin确定为了官方开发语言,作为一名Android开发鸟,怎么能不及时尝尝鲜呢? Kotlin的简要介绍 在开发之 ...

  2. Kotlin系列之Kotlin初体验

    这一篇我们开始Kotlin代码之旅,一步步入门Kotlin. 一.Kotlin开发工具 Kotlin语言在开发之初,它的语言和插件工具是同步开发的. 这里推荐IntelliJ IDEA15及以上,ID ...

  3. MapReduce编程初体验

    需求:在给定的文本文件中统计输出每一个单词出现的总次数 第一步: 准备一个aaa.txt文本文档 第二步: 在文本文档中随便写入一些测试数据,这里我写入的是 hello,world,hadoop he ...

  4. 树莓派2代B model 上手初体验,不用显示器,Python GPIO 点亮一颗LED

    开题:[好东西,值得研究!] 标题:树莓派2代B model 上手初体验,不用显示器,Python GPIO 点亮一颗LED [知识普及] 1,树莓派各版本对比: 2,树莓派2代BModel 主板,图 ...

  5. Polygon zkEVM的pil-stark Fibonacci状态机初体验

    1. 引言 前序博客: Polygon zkEVM 基本概念 第5章 "一个例子--Fibonacci state machine" 实操主要见: 2022年8月8日Jordi B ...

  6. 【你好Resilience4j】一:Resilience4j之初体验

    每日一句 健身和读书,是世界上成本最低的升值方式:而懒,是你通往牛逼的路上最大的敌人. 目录 为什么要使用Resilience4j Resilience4j介绍 Resilience4j模块 初体验 ...

  7. 【ChatGPT初体验与Android的集成使用】

    ChatGPT初体验与Android的集成使用 前言 创建自己的API KEY Android端的集成 代码 总结 前言 ChatGPT凭借着强大的AI功能火的一塌糊涂,由于其官网在国内不能访问,很多 ...

  8. 三、Hadoop系统应用之Hadoop集群测试及初体验(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)

    Hadoop集群搭建前安装准备参考: 一.Hadoop系统应用之安装准备(一)(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7) 一.Ha ...

  9. Rasa课程、Rasa培训、Rasa面试系列之:Rasa 3.x部署安装初体验

    Rasa课程.Rasa培训.Rasa面试系列之:Rasa 3.x部署安装初体验 Rasa 3.x部署安装 进入Ananconda系统,新建rasa虚拟环境 conda create --name in ...

最新文章

  1. Win32下内存分配简单示例 - 使用CFree
  2. C#中的默认访问修饰符
  3. Response_案例1_重定向_特点
  4. ASP.NET WEBAPI设计(文摘)
  5. Git标签tag及tag远程同步
  6. linux下远程登录如何退出,Ubuntu 中rdesktop如何切换和退出远程桌面
  7. Java游戏触屏处理,非触屏java游戏转换为触屏游戏工具使用方法
  8. Java设计模式学习总结(15)——行为型模式之责任链模式
  9. 计算机仿真电路实验感想,电路计算机仿真 实验报告.doc
  10. c语言引用与指针有什么区别,Java引用与C语言指针的区别
  11. Js时间相关处理函数
  12. Qt对图像的二值化处理
  13. JPA语法大全 特别是JPA的不等于
  14. IAP程序升级(全网最全)
  15. 开机出现recovering journal解决办法
  16. 初识C语言----完结篇
  17. Windows下安装ES
  18. Java 遍历map(Java8)
  19. 第3章 软件测试过程
  20. mysql select后面能跟多少个表_mysql查询语句中,FROM后面可以跟具体的表名,也可以跟一个查询结果...

热门文章

  1. 文献 | fMRI入门指南
  2. Cloudera Manager环境搭建【二】
  3. Loadrunner11 录制手机App脚本多种方法介绍
  4. 查看虚拟机vmware下linux的ip
  5. oracle rman crosscheck,rman crosscheck作用
  6. springboot中Error creating bean with name ‘keyExpiredListener‘ defined in f
  7. ws2812C驱动示例主控芯片为HC32F460系列
  8. OTA线下攻防战 | 一点财经
  9. 抖音名字怎么改不了_抖音名字怎么改,抖音名字改不了,抖音名字已重置什么意思...
  10. 使用Cloudflare Workers部署博客