gradle自定义sourcesets需明确指定源码和资源路径:java项目用srcdirs替换默认路径,android项目在android块内逐项映射;注意srcdir追加、srcdirs替换,路径须为相对路径且配置后需同步。

Gradle 默认按约定识别 src/main/java 和 src/main/resources 等路径,但实际项目中常需适配旧结构、模块化拆分或特殊组织方式。自定义 sourceSets 的核心是明确告诉 Gradle “从哪找代码”和“哪些要排除”,而不是简单覆盖——尤其要注意 srcDir 是追加、srcDirs 是替换。
Java 项目:用 srcDirs 替换默认源目录
若整个项目源码放在 src 下(无 main 子目录),需清空默认路径并指定新位置:
- 在
build.gradle中启用 Java 插件后,直接配置sourceSets -
main.java.srcDirs = ['src']—— 这会完全替换默认的src/main/java,只认src目录下的 Java 文件 - 同理设置资源:
main.resources.srcDirs = ['src/resources']或合并为['src', 'src/resources'](注意避免父子目录嵌套) - 测试代码同样处理:
test.java.srcDirs = ['test']
Android 项目:映射多目录 + 调整组件路径
Android 的 sourceSets 在 android { } 块内声明,且各组件(java、res、assets 等)可独立指定:
- 旧工程结构(所有源码混在
src/)需逐项映射:java.srcDirs = ['src']、res.srcDirs = ['res']、assets.srcDirs = ['assets'] - 使用
setRoot('tests')可整体迁移androidTest源集,它会把src/androidTest/**全部移到tests/** - 想叠加多个资源目录(如按功能分模块),用数组:
res.srcDirs = ['src/main/res', 'src/main/res-ad', 'src/main/res-player'] - 指定非标准清单文件:
manifest.srcFile 'AndroidManifest.xml'(路径相对于项目根目录)
高级用法:动态路径 + 条件化配置
结合 Groovy 或 Kotlin DSL 的表达能力,可让配置更灵活:
- 批量添加多个子目录:定义列表
def dirs = ['main', 'common', 'utils'],再用dirs.each { dir -> java.srcDirs "src/$dir/java" } - 根据构建类型切换 Manifest:
if (project.hasProperty('debug')) { manifest.srcFile 'src/debug/AndroidManifest.xml' } - 排除特定文件:
java { exclude 'legacy/**' },防止旧代码参与编译 - 修改 JNI 库路径:
jniLibs.srcDirs = ['libs'],让 Gradle 从libs/加载 so 文件
注意事项:避免常见陷阱
配置生效依赖几个关键点:
-
srcDir是追加,srcDirs是赋值替换——误用srcDir可能导致重复扫描 - 路径必须存在且为相对路径(相对于项目根目录),不能用绝对路径
- Android 中
sourceSets必须写在android { }内;纯 Java 项目则直接写在脚本顶层 - 修改后需同步项目(Android Studio 点击 “Sync Now”),否则 IDE 可能仍按旧路径索引











