我的Gradle插件如何定义依赖AGP 7.0.0内置任务的自定义任务?
问题原因
AGP 7.0+ 重构后的新 Variant API 调整了配置阶段的执行顺序:ApplicationAndroidComponentsExtension.onVariants() 回调触发时,AGP 还未完成内置构建任务(包括 merge*Assets 系列任务)的注册流程,此时直接通过任务名查找任务会触发立即解析,自然找不到对应任务。
解决方案
方案1(官方推荐,稳定性最高)
不需要手动查找 merge*Assets 任务,直接通过 Variant 提供的资产源注册 API 绑定你的生成任务,AGP 会自动处理任务依赖和输入路径配置:
import com.android.build.api.variant.ApplicationAndroidComponentsExtension import org.gradle.api.DefaultTask import org.gradle.api.file.DirectoryProperty import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction // 你的自定义生成任务示例 abstract class GenerateStuffTask : DefaultTask() { @get:OutputDirectory abstract val outputDir: DirectoryProperty @TaskAction fun generate() { // 你的资产生成逻辑 outputDir.get().asFile.mkdirs() // 生成文件逻辑... } } // 插件中配置逻辑 val androidComponents = project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java) androidComponents.onVariants { variant -> // 惰性注册你的生成任务 val generateTask = project.tasks.register<GenerateStuffTask>( "generate${variant.name.replaceFirstChar { it.uppercase() }}Stuff" ) { it.outputDir.set(project.layout.buildDirectory.dir("generated/stuff/${variant.name}")) // 其他任务参数配置... } // 注册任务输出为变体的生成资产源,AGP自动将其加入merge*Assets的输入,自动建立依赖 variant.sources.assets?.addGeneratedSourceDirectory(generateTask, GenerateStuffTask::outputDir) }
方案2(仅适用于需要额外自定义mergeAssets任务的场景)
如果确实需要直接配置 merge*Assets 任务,使用 Gradle 惰性查找API tasks.named() 替代直接获取,该方法会等所有任务注册完成后再执行配置逻辑,不会触发任务未找到报错:
androidComponents.onVariants { variant -> val generateTask = project.tasks.register<GenerateStuffTask>( "generate${variant.name.replaceFirstChar { it.uppercase() }}Stuff" ) // 惰性查找mergeAssets任务,任务注册后才执行配置 project.tasks.named<com.android.build.gradle.tasks.MergeAssets>( "merge${variant.name.replaceFirstChar { it.uppercase() }}Assets" ) { mergeTask -> mergeTask.dependsOn(generateTask) mergeTask.source(generateTask.map { it.outputDir }) } }
两种方案都兼容 AGP 7.0+ 所有正式版本,不需要依赖AGP内部未公开API,不会出现任务找不到的问题。
内容的提问来源于stack exchange,提问作者Dario Scoppelletti
相关产品推荐
相关产品推荐

