Gradle sourceSet资源合并:解决重叠文件覆盖问题
解决Gradle中sourceSet资源合并时变体文件覆盖主文件的问题
你的核心需求是让appVariant sourceSet的资源扩展(并覆盖)main的资源,同时避免修改main本身的配置,也不用额外的common sourceSet。之前的思路问题在于对Gradle sourceSet的source和from方法的理解偏差,以下是符合Gradle设计的最优方案:
正确的资源合并配置
直接在appVariant的resources中通过from引入main的资源树,同时通过文件引入顺序或重复策略确保变体文件优先:
sourceSets { main { resources { srcDirs = ['src/main/resources'] } } appVariant { resources { // 方案1:先引入main的资源(排除冲突的foo.properties),再引入变体自己的资源 from sourceSets.main.resources.files.matching { exclude 'foo.properties' } srcDir 'src/appVariant/resources' // 方案2:直接合并所有资源,通过重复策略让后引入的变体文件覆盖主文件 // from sourceSets.main.resources // srcDir 'src/appVariant/resources' // // 重复文件时保留最后引入的(变体目录在后,所以覆盖main的) // duplicatesStrategy = DuplicatesStrategy.INCLUDE } } }
为什么之前的写法有问题
source(sourceSets.main.resources):这是把main的资源目录添加为appVariant的源目录,Gradle默认会让主sourceSet的文件覆盖变体文件,且无法在这个链式调用中直接设置重复策略。source(sourceSets.main.resources).exclude('foo.properties'):source()返回的是sourceSet对象,不是文件树,所以exclude不会作用到刚添加的main资源上,自然无效。source(sourceSets.main.resources.exclude('foo.properties')):这里直接修改了sourceSets.main.resources的配置,属于副作用操作,会影响依赖main的其他任务,绝对不可取。
实现runAppVariant任务
application插件默认只为main生成run任务,要为appVariant创建独立的运行任务,只需注册一个JavaExec任务:
tasks.register('runAppVariant', JavaExec) { // 使用appVariant的运行时类路径 classpath = sourceSets.appVariant.runtimeClasspath // 主类如果在main里就用main的,否则替换成appVariant的主类 mainClass = sourceSets.main.mainClass.get() // 可选:设置独立的工作目录,避免和main的运行环境冲突 workingDir = project.layout.buildDirectory.dir('run/appVariant').get().asFile }
执行./gradlew runAppVariant就能基于appVariant的配置运行应用了。
内容的提问来源于stack exchange,提问作者Alden
相关产品推荐
相关产品推荐

