仅资源不同时,能否仅执行一次Minification生成两款APK?
解决方案:复用编译与混淆产物,仅差异化打包资源
1. 重构模块结构,拆分核心代码与差异化资源
- 保留一个核心模块(比如
:core),存放所有通用Java/Kotlin源码、非差异化资源(通用布局、字符串等) - 创建两个资源模块(比如
:brandA-res、:brandB-res),仅存放各自的品牌标识、差异化XML资源,无需包含任何源码,仅作为资源依赖容器
2. 配置核心模块,仅执行一次编译与混淆
在核心模块的build.gradle中,聚焦通用代码的编译与混淆,关闭APK打包,只输出AAR产物:
android { compileSdk 34 defaultConfig { minSdk 21 targetSdk 34 applicationId "com.example.app" } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } // 仅输出AAR,跳过APK打包流程 libraryVariants.all { variant -> variant.outputs.each { output -> output.outputFileName = "core-${variant.name}.aar" } } } dependencies { implementation 'androidx.core:core-ktx:1.12.0' // 其他通用依赖 }
3. 配置资源模块,依赖核心模块并差异化打包
以:brandA-res为例,其build.gradle配置如下(:brandB-res仅需修改applicationId和资源目录):
android { compileSdk 34 defaultConfig { minSdk 21 targetSdk 34 applicationId "com.example.app.brandA" // 指定品牌专属资源目录 sourceSets { main { res.srcDirs = ['src/main/res'] // 可添加额外品牌资源目录,比如src/main/brand-specific-res } } } buildTypes { release { // 禁用当前模块混淆,直接复用核心模块的混淆产物 minifyEnabled false // 引用核心模块的混淆映射文件,保证崩溃日志可反混淆 consumerProguardFiles project(':core').file('build/outputs/mapping/release/mapping.txt') } } } dependencies { // 依赖核心模块的AAR,复用编译与混淆后的代码 implementation project(':core') // 品牌专属依赖(如有) }
4. 优化构建命令,确保核心模块仅构建一次
执行构建时,先构建核心模块,再构建两个资源模块:
./gradlew :core:assembleRelease :brandA-res:assembleRelease :brandB-res:assembleRelease
Gradle会自动缓存核心模块的构建产物,资源模块构建时直接复用,不会重复执行编译和Minification步骤。
关键原理
- 核心模块作为Library输出AAR,包含编译后的字节码、混淆映射文件,资源模块依赖该AAR,无需重新编译源码
- 资源模块仅负责打包自身差异化资源+核心模块代码,跳过耗时的Minification步骤
- 混淆映射文件的引用保证了后续崩溃日志可正确反混淆
内容的提问来源于stack exchange,提问作者Nilzor
相关产品推荐
相关产品推荐

