多模块项目中Gradle插件生成flavorDimensions及productFlavors遇阻
解决AGP DSL锁定异常:跨模块生成Flavor配置
问题重现
开发的Gradle插件用于自动生成Android模块的flavorDimensions和productFlavors:
- 直接将插件应用到Android模块时,功能正常;
- 将插件应用到项目中其他非Android模块时,Gradle同步抛出
AgpDslLockedException,提示无法修改flavorDimensions,因为配置已被读取锁定。
插件核心代码:
class MyPlugin : Plugin<Project> { override fun apply(project: Project) { // 遍历根项目所有子项目寻找Android模块 project.rootProject.subprojects.forEach { subproject -> val android = subproject.extensions.findByName("android") as? AppExtension ?: return@forEach // 应用到非Android模块时触发异常 android.flavorDimensions.add("dimension") android.productFlavors.create("flavor") { it.dimension = "dimension" } } } }
异常信息:
It is too late to modify flavorDimensions.
It has already been read to configure this project.
Consider either moving this call to be during evaluation, or using the variant API.
问题原因
当插件应用到非Android模块(如other模块)时,遍历子项目执行修改操作的时机晚于Android模块的配置评估阶段。AGP会在项目评估完成后锁定DSL配置,禁止修改flavorDimensions这类会影响变体生成的核心配置。
解决方案
核心思路是:确保在Android插件应用后、DSL配置锁定前修改Flavor相关设置,通过监听子项目的Android插件加载事件实现。
修改后的插件代码:
import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.LibraryExtension import org.gradle.api.Plugin import org.gradle.api.Project class MyPlugin : Plugin<Project> { override fun apply(project: Project) { // 监听所有子项目的Android插件应用事件 project.rootProject.subprojects.forEach { subproject -> // 处理Android应用模块 subproject.plugins.withId("com.android.application") { val android = subproject.extensions.getByType(ApplicationExtension::class.java) // 在插件刚加载时修改配置,此时DSL未锁定 android.flavorDimensions.add("dimension") android.productFlavors.create("flavor") { it.dimension = "dimension" } } // 可选:处理Android库模块 subproject.plugins.withId("com.android.library") { val android = subproject.extensions.getByType(LibraryExtension::class.java) android.flavorDimensions.add("dimension") android.productFlavors.create("flavor") { it.dimension = "dimension" } } } } }
方案说明
- 使用
plugins.withId监听子项目中Android插件的加载事件,此时Android扩展已初始化,且DSL配置处于可修改状态; - 不管插件应用到项目中哪个模块,只要根项目下的子项目应用了Android插件,就会自动执行Flavor配置生成逻辑;
- 避免了直接遍历子项目时因生命周期时机错误导致的DSL锁定异常。
补充说明
若之前尝试beforeEvaluate无效,大概率是因为未针对子项目的评估阶段操作,而是在插件所在模块的评估周期中执行,时机仍晚于Android模块的配置锁定点。上述方案通过绑定Android插件的加载事件,能精准命中安全修改时机。
内容的提问来源于stack exchange,提问作者Philipp Fahlteich
相关产品推荐
相关产品推荐

