4. 根 build.gradle 与模块 build.gradle 职责拆分
为什么需要拆分根脚本与模块脚本
多模块 Android 工程里,根 build.gradle 与各模块 build.gradle 承担的是两类不同职责。根脚本负责“全局约定”:插件版本、公共插件是否统一应用、子模块通用配置;模块脚本负责“局部差异”:本模块是 com.android.application 还是 com.android.library、自己的 namespace、编译版本、依赖坐标。若把公共插件和版本变量散落在每个模块里,就会出现同一版本号写多份、升级时漏改、模块间配置漂移的问题。
拆分后的文件结构
以三模块工程为例,拆分后的职责边界如下:
| 文件 | 职责 | 关键内容 |
|---|---|---|
根 build.gradle | 全局插件版本、公共 SDK 变量、子模块通用仓库 | plugins 块带 apply false、ext 变量、subprojects 块 |
app/build.gradle | 应用模块专属配置 | com.android.application、namespace、applicationId、模块依赖 |
core/build.gradle | 库模块专属配置 | com.android.library、namespace、api/implementation 依赖 |
feature/build.gradle | 库模块专属配置 | com.android.library、namespace、模块依赖 |
根 build.gradle 写法
// 根 build.gradle
plugins {
id 'com.android.application' version '8.2.0' apply false
id 'com.android.library' version '8.2.0' apply false
id 'org.jetbrains.kotlin.android' version '1.9.22' apply false
}
ext {
compileSdkVersion = 34
minSdkVersion = 24
targetSdkVersion = 34
}
subprojects {
repositories {
google()
mavenCentral()
}
}
关键点:apply false 表示只在根脚本解析插件版本,不在此处应用插件;ext 中的变量可被所有子模块通过 rootProject.ext.compileSdkVersion 读取;subprojects 块统一为所有子模块添加仓库,避免每个模块重复写 repositories。
模块 build.gradle 写法
// app/build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.demo.app'
compileSdk rootProject.ext.compileSdkVersion
defaultConfig {
applicationId 'com.demo.app'
minSdk rootProject.ext.minSdkVersion
targetSdk rootProject.ext.targetSdkVersion
versionCode 1
versionName '1.0'
}
}
dependencies {
implementation project(':core')
implementation project(':feature')
}
// core/build.gradle
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.demo.core'
compileSdk rootProject.ext.compileSdkVersion
defaultConfig {
minSdk rootProject.ext.minSdkVersion
}
}
dependencies {
api 'androidx.core:core-ktx:1.12.0'
}
模块脚本不再写插件版本号,SDK 版本统一从 rootProject.ext 读取。这样升级 AGP 或 compileSdk 时只需改根脚本一处。
验证构建结果一致
拆分完成后,用以下命令验证配置是否生效且构建结果与拆分前一致:
# 1. 查看各模块解析到的插件版本
./gradlew :app:dependencies --configuration classpath
# 2. 查看编译 SDK 是否统一
./gradlew :app:properties | grep -i compileSdk
# 3. 执行完整构建
./gradlew clean assembleDebug
# 4. 对比拆分前后 APK 的 versionCode / versionName
./gradlew :app:assembleDebug
aapt dump badging app/build/outputs/apk/debug/app-debug.apk | head -1
验证通过条件:
assembleDebug 成功;aapt dump badging 输出的 versionCode 与 versionName 与拆分前一致;各模块 compileSdk 均为 34。若出现 Could not find method compileSdk(),检查根脚本 ext 变量名与模块引用名是否拼写一致。常见问题与排查
Plugin [id: 'com.android.application'] was not found:根脚本plugins块缺少版本声明,或settings.gradle的pluginManagement未配置仓库。- 模块中
rootProject.ext.compileSdkVersion报null:根脚本ext块在subprojects之后才执行,需确保ext块位于文件顶部。 - 子模块重复应用插件导致
Cannot add task 'clean' as a task with that name already exists:检查是否在根脚本误用了apply plugin而非apply false。