跳转到正文
YGJoon
返回

Android Kotlin KSP 编译期代码生成

编辑文章

KSP 基础

项目配置

plugins {
    kotlin("kapt")
    id("com.google.devtools.ksp") version "1.9.24-1.0.20"
}

dependencies {
    implementation("com.squareup.moshi:moshi:1.15.1")
    ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.1")
}

Gradle 任务:./gradlew kspDebugKotlin。

自定义 Processor

1. 定义注解

@Target(AnnotationTarget.CLASS)
annotation class AutoRegister(val path: String)

2. 写 Processor

class AutoRegisterProcessor(env: SymbolProcessorEnvironment) : SymbolProcessor {
    private val codeGenerator = env.codeGenerator
    private val logger = env.logger

    override fun process(resolver: Resolver): List<KSAnnotated> {
        val symbols = resolver.getSymbolsWithAnnotation(AutoRegister::class.qualifiedName!!)
        symbols.filterIsInstance<KSClassDeclaration>().forEach { clazz ->
            val path = clazz.getAnnotationsByType(AutoRegister::class).first().path
            generateRegistry(clazz, path)
        }
        return emptyList()
    }

    private fun generateRegistry(clazz: KSClassDeclaration, path: String) {
        val packageName = clazz.packageName.asString()
        val fileName = "${clazz.simpleName.asString()}_Registry"
        codeGenerator.createNewFile(Dependencies(false, clazz.containingFile!!), packageName, fileName).use { out ->
            out.writer().use { writer ->
                writer.appendLine("package $packageName")
                writer.appendLine("object $fileName { const val PATH = \"$path\" }")
            }
        }
    }
}

3. 注册 Processor

resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider

com.example.ksp.AutoRegisterProcessorProvider

Provider:

class AutoRegisterProcessorProvider : SymbolProcessorProvider {
    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
        return AutoRegisterProcessor(environment)
    }
}

在 Android 中使用

性能与调试

问题说明解决方案
处理器执行缓慢遍历符号时重复扫描使用 resolver.getSymbolsWithAnnotation 缓存结果
调试困难无断点使用 logger.warn 输出调试信息
增量编译失效输出文件未声明依赖Dependencies(aggregating = false, ...) 指定输入

调试命令:./gradlew :app:kspDebugKotlin --info。

与 KAPT 对比

对比项KAPTKSP
支持语言Kotlin/JavaKotlin
性能需生成 Java Stub,偏慢原生处理 Kotlin AST,更快
生态支持旧插件众多Moshi、Room、Hilt 已提供 KSP 版本

最佳实践

  1. 优先使用官方提供的 KSP 依赖(Room、Hilt、Moshi)。
  2. 自研 Processor 时控制生成文件数量,避免冗余代码。
  3. 在 CI 中开启 --no-build-cache 定位问题,再逐步恢复增量配置。

总结

KSP 给 Kotlin 带来高效的编译期扩展能力。Android 项目可通过 KSP 实现自动路由、数据模型生成等,提高开发效率。掌握基本编写流程与调试方式,能让团队更好地利用编译期工具构建高质量基础设施。


编辑文章
分享这篇文章:

上一篇
Android Kotlin Room 数据库进阶实践
下一篇
Android Kotlin Multiplatform 入门