Android Gradle Release构建替换主srcDir遇重复类报错求助
解决Android Release构建中替换源码目录导致的重复类问题
我之前也踩过一模一样的坑!核心问题其实是你没彻底替换掉原来的主源码目录——默认情况下Android Gradle插件会把src/main/java加入所有变体的源码集,如果你只是追加处理后的目录而不移除原目录,就会同时包含两份相同的类文件,自然报重复类错误。
下面是我验证过的解决方案,分两步走:
1. 先定义可靠的源码预处理任务
首先把预处理逻辑封装成独立的Copy任务,明确输入输出路径,这样Gradle能正确做增量构建,避免重复执行:
task processReleaseSources(type: Copy) { // 输入:原main源码目录 from "src/main/java" // 输出:处理后的代码放在build目录下的generated文件夹(避免和其他目录冲突) into "$buildDir/generated/sources/processed/release/java" // 这里替换成你的正则处理逻辑 filter { line -> line.replaceAll(/旧的正则匹配规则/, "新的替换内容") } // 只处理Java文件,有Kotlin的话可以再加一行include "**/*.kt" include "**/*.java" }
2. 给Release变体单独替换源码集
接下来找到Release变体,把它的源码集里的原src/main/java去掉,换成预处理后的目录,同时确保编译任务依赖预处理任务:
android { // 常规配置:compileSdk、defaultConfig、buildTypes等 compileSdk 34 defaultConfig { applicationId "com.your.app" minSdk 24 targetSdk 34 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { // Debug构建保持原源码目录不变 } } // 遍历所有变体,只修改Release的源码集 applicationVariants.all { variant -> if (variant.name.equalsIgnoreCase("release")) { variant.sourceSets.each { sourceSet -> // 移除原main java目录 sourceSet.java.srcDirs = sourceSet.java.srcDirs - file("src/main/java") // 添加预处理后的目录 sourceSet.java.srcDirs += processReleaseSources.outputs.files } // 确保编译Release代码前先执行预处理任务 variant.javaCompileProvider.get().dependsOn(processReleaseSources) } } }
关键注意点
- 如果用Kotlin开发,记得同时处理
sourceSet.kotlin.srcDirs,逻辑和Java目录一致; - 输出路径一定要放在
build目录下,避免把生成的代码提交到版本库; - 用
variant.javaCompileProvider.get()而非直接引用compileReleaseJavaWithJavac,是为了兼容不同Gradle版本的API变化; - 增量构建:因为明确了
from和into,Gradle会自动检测原文件变化,只有源码修改时才会重新执行预处理任务。
这样配置后,Release构建就只会使用预处理后的代码,Debug构建还是用原源码,也不会出现重复类的问题了。
内容的提问来源于stack exchange,提问作者Nobby_Nobody
相关产品推荐
相关产品推荐

