创建模块并定义模块类型:插件应用与模块声明
Gradle 多模块项目中的每个子模块都是一个独立的构建单元,其类型由所应用的插件决定。正确声明模块并选择对应插件是实现模块化拆分的起点。本章将系统讲解如何在 settings.gradle 中注册模块、如何为模块应用 Java Library、Application、Kotlin 和 Android 插件,以及各插件之间的关键差异。
1. 模块声明与目录结构
在 Gradle 多模块项目中,所有子模块必须在根项目的 settings.gradle(或 settings.gradle.kts)中显式声明。每个模块对应一个独立的子目录,该目录下必须包含 build.gradle 文件。
命名规范: 模块名称通常采用小写连字符形式(如
core-utils),目录名与模块名保持一致。避免使用驼峰或空格。
// settings.gradle(Groovy DSL)
rootProject.name = 'my-multi-module'
include 'core-library'
include 'app'
include 'toolkit'
include 'android-app'
// 对应的目录结构
my-multi-module/
├── settings.gradle
├── build.gradle // 根项目构建脚本
├── core-library/
│ └── build.gradle
├── app/
│ └── build.gradle
├── toolkit/
│ └── build.gradle
└── android-app/
└── build.gradle
2. 插件类型与应用方式
每个子模块的 build.gradle 通过 plugins { id '...' } 块声明构建类型。下表列出最常用的四大插件类型及其适用场景。
| 插件 ID | 模块类型 | 适用场景 | 生成产物 |
|---|---|---|---|
java-library |
Java 库 | 封装可复用的 Java 工具类、业务逻辑、数据模型 | JAR |
application |
Java 应用程序 | 包含 main 方法的可运行 Java 程序 | 可执行 JAR / 启动脚本 |
org.jetbrains.kotlin.jvm |
Kotlin 库 | 纯 Kotlin 编写的公共模块,可被 Java/Kotlin 调用 | JAR(含 Kotlin 标准库) |
com.android.application |
Android 应用 | 构建 Android APK 的入口模块 | APK / AAB |
插件与语言配置的关系: 应用
java-library 或 application 后,Gradle 会自动启用 Java 编译任务;若需混合 Kotlin 代码,应额外添加 org.jetbrains.kotlin.jvm 插件,或直接使用 org.jetbrains.kotlin.jvm 代替 Java 插件。
3. 各模块构建脚本示例
3.1 Java 库模块(core-library)
// core-library/build.gradle
plugins {
id 'java-library'
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
// 对外暴露的 API 依赖
api 'com.google.guava:guava:32.0.1-jre'
// 内部实现依赖
implementation 'org.slf4j:slf4j-api:2.0.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}
3.2 应用模块(app)
// app/build.gradle
plugins {
id 'application'
}
application {
mainClass = 'com.example.Main'
}
dependencies {
implementation project(':core-library')
implementation 'org.slf4j:slf4j-simple:2.0.0'
}
3.3 Kotlin 库模块(toolkit)
// toolkit/build.gradle
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.9.0'
}
kotlin {
jvmToolchain(17)
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
implementation project(':core-library')
testImplementation 'org.jetbrains.kotlin:kotlin-test'
}
3.4 Android 应用模块(android-app)
// android-app/build.gradle
plugins {
id 'com.android.application' version '8.1.0'
id 'org.jetbrains.kotlin.android' version '1.9.0'
}
android {
namespace 'com.example.androidapp'
compileSdk 34
defaultConfig {
applicationId 'com.example.androidapp'
minSdk 21
targetSdk 34
versionCode 1
versionName '1.0'
}
}
dependencies {
implementation project(':core-library')
implementation project(':toolkit')
implementation 'androidx.appcompat:appcompat:1.6.1'
}
4. 模块类型选择与插件应用流程
下面的 SVG 图展示了典型多模块项目中各模块的插件选择关系。根项目不应用业务插件,仅负责协调子模块;子模块根据职责(库、应用、Android 等)选择特定插件。
5. 常见错误与避坑指南
避免插件重复应用: 如果一个模块同时应用
java-library 和 application,将导致任务冲突(jar vs distZip)。库模块和可运行模块应严格分离。
- Kotlin 插件版本与 Gradle 版本不匹配: 使用
org.jetbrains.kotlin.jvm时,插件版本必须与编译环境兼容。建议查看 Kotlin Gradle 插件兼容矩阵。 - Android 模块必须放在单独的项目或子模块中: 不要在同一个模块中同时使用
com.android.application和java-library;若共享代码,应抽取为android-library模块。 - 模块名称与目录名不一致: 如果
include 'my-module'但目录名是my_module,Gradle 会报模块未找到错误。目录名需与include中的名称完全一致(大小写敏感)。
6. 调试与验证
创建模块后,可以使用以下命令验证模块是否被正确识别:
# 列出所有项目(含根项目和子模块)
gradle projects
# 查看特定模块的构建任务
gradle :app:tasks
# 编译单个模块
gradle :core-library:build
实践建议: 在大型多模块项目中,建议为每个模块单独执行
gradle :模块名:check 确保编译通过,再逐步联调。利用 gradle build --dry-run 可预览任务执行顺序,避免依赖循环。