You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用addGeneratedSourceDirectory生成Kotlin代码失败问题咨询

生成Kotlin代码的Gradle任务无法正常执行问题解决

问题场景

原本使用以下Gradle配置生成Java代码并集成到Android应用中是完全正常的:

variant.sources.java?.addGeneratedSourceDirectory(
    project.tasks.register("${variant.name}GenerateBackendsEnum", GenerateBackendsTask::class.java) {
        it.jniDir.set(project.layout.projectDirectory.dir("src/main/jni"))
        it.outputFolder.set(project.layout.buildDirectory.dir("generated/backendsEnum/${variant.name}"))
    },
    GenerateBackendsTask::outputFolder
)

但将配置改为生成Kotlin代码(替换为variant.sources.kotlin!!)后,出现以下异常:

  • 应用构建时,生成Kotlin代码的任务不会自动执行(Java版本的任务会正常触发)
  • 手动执行生成任务后,Kotlin文件已生成到磁盘,但后续构建不会将其编译为.class文件,导致运行时无法使用该代码

注:应用主体为Java代码,但app/src/main/kotlin下的手写Kotlin文件可正常编译集成。

解决方案

1. 显式绑定任务与Kotlin编译任务的依赖

AGP对Java源码的处理会自动关联生成任务与编译任务,但Kotlin没有这个自动逻辑,需要手动声明依赖:

val generateTask = project.tasks.register("${variant.name}GenerateBackendsEnum", GenerateBackendsTask::class.java) {
    it.jniDir.set(project.layout.projectDirectory.dir("src/main/jni"))
    it.outputFolder.set(project.layout.buildDirectory.dir("generated/backendsEnum/${variant.name}"))
}

// 添加生成目录到Kotlin源码集合
variant.sources.kotlin!!.addGeneratedSourceDirectory(generateTask, GenerateBackendsTask::outputFolder)
// 让Kotlin编译任务依赖生成任务,确保编译前先执行代码生成
project.tasks.named("compile${variant.name.replaceFirstChar { it.uppercase() }}Kotlin") {
    dependsOn(generateTask)
}

2. 直接将生成目录绑定到SourceSet

另一种更直接的方式是把生成目录添加到对应SourceSet,同时绑定任务依赖:

val generateTask = project.tasks.register("${variant.name}GenerateBackendsEnum", GenerateBackendsTask::class.java) {
    it.jniDir.set(project.layout.projectDirectory.dir("src/main/jni"))
    it.outputFolder.set(project.layout.buildDirectory.dir("generated/backendsEnum/${variant.name}"))
}

// 将生成目录添加到Kotlin源码集合
variant.sourceSets.getByName("main").kotlin.srcDir(generateTask.map { it.outputFolder })
// 确保编译任务在生成任务完成后执行
project.tasks.named("compile${variant.name}Kotlin") {
    dependsOn(generateTask)
}

问题根源

AGP对Java源码的addGeneratedSourceDirectory方法会自动建立生成任务与Java编译任务的依赖关系,但Kotlin源码的处理逻辑未包含该自动关联,必须手动声明依赖,才能保证生成任务在编译前执行,且编译任务能识别到生成的源码。

内容的提问来源于stack exchange,提问作者Chris Boyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:42:28