🔧 模块化工程骨架搭建:Gradle多模块配置、模块命名规范、依赖管理统一版本
1.1 模块化架构设计目标
模块化不是简单的文件夹拆分,而是一种编译隔离、职责分离、复用优先的架构方案。在 ViewModel 与模块化搭配场景中,我们需要确保每个模块可独立编译、测试,同时通过 Gradle 统一管理版本,避免依赖地狱。
- 编译隔离:修改 feature 模块不会触发 core 模块的全量编译。
- 职责边界:data、domain、presentation 层严格分层,依赖单向。
- 版本一致:所有第三方库、Kotlin 版本、AGP 版本集中定义,避免升级遗漏。
📌 实践中推荐采用“三层四模块”模式:
app(入口)、:feature:*(业务页面)、:lib:core(基础工具)、:lib:data(数据/网络/数据库)。1.2 Gradle 多模块配置(settings.gradle.kts)
根目录下的 settings.gradle.kts 是模块发现的起点。必须显式声明所有子模块路径,并启用 Version Catalog。
// settings.gradle.kts
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "ViewModelModularApp"
// 模块注册
include(":app")
include(":feature:login")
include(":feature:home")
include(":lib:core")
include(":lib:data")
include(":lib:network")
include(":lib:test-utils")
💡 模块路径使用冒号分隔层级,例如
:feature:login 对应文件系统 feature/login/ 目录。1.3 模块命名规范
| 层级 | 前缀 | 示例 | 职责 |
|---|---|---|---|
| 应用入口 | :app | :app | Application、Activity、全局依赖注入 |
| 业务特征 | :feature: | :feature:login | 页面级 ViewModel、Fragment、导航图 |
| 功能库 | :lib: | :lib:core | 基类、扩展函数、通用工具 |
| 数据层 | :lib:data | :lib:network | Repository、API 接口、数据库 DAO |
| 测试共享 | :lib:test-utils | :lib:test-utils | Mock 数据、测试规则、ViewModel 测试辅助 |
规范遵循 小写 + 连字符 命名,严禁使用下划线或大写字母。libs.versions.toml 中的依赖别名也需保持一致。
1.4 依赖管理统一版本(Version Catalog)
Android 官方推荐使用 libs.versions.toml 集中管理版本。文件位于 gradle/ 目录下,所有模块通过 libs.* 引用依赖。
// gradle/libs.versions.toml
[versions]
kotlin = "1.9.22"
agp = "8.2.2"
compose-bom = "2024.02.00"
lifecycle = "2.7.0"
navigation = "2.7.7"
hilt = "2.50"
retrofit = "2.9.0"
[libraries]
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
retrofit-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
在各模块的 build.gradle.kts 中使用方式:
// feature/login/build.gradle.kts
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.hilt)
}
android {
namespace = "com.example.feature.login"
compileSdk = 34
defaultConfig { minSdk = 24 }
}
dependencies {
implementation(libs.lifecycle.viewmodel.ktx)
implementation(libs.hilt.android)
kapt(libs.hilt.android.compiler)
implementation(project(":lib:core"))
implementation(project(":lib:data"))
}
⚠️ 注意:
kapt、ksp 等注解处理器版本也要统一纳入 catalog,避免编译时使用不同版本的 annotation processor 导致冲突。1.5 模块化工程骨架流程图
下图展示了典型的 ViewModel 模块化工程中各模块的依赖关系与数据流向。
💡 依赖方向自顶向下:
app → feature → lib。feature 模块不应直接依赖其他 feature 模块,若需共享数据应通过 lib:core 或导航路由实现。1.6 实现流程(6步搭建)
- 创建项目:Android Studio 新建 Empty Activity 项目,删除默认
app模块以外的多余文件。 - 生成目录结构:在根目录下创建
feature/、lib/文件夹,并在每个子文件夹内新建build.gradle.kts和src/main/目录。 - 配置 settings.gradle.kts:注册所有模块路径,详见 1.2 节。
- 创建 Version Catalog:在
gradle/下新建libs.versions.toml,定义版本、库、插件。 - 编写根 build.gradle.kts:只声明插件解析,具体插件由子模块通过
alias引入。 - 编写各模块 build.gradle.kts:按角色配置 android 插件、namespace、dependencies(使用
libs.*和project())。
1.7 调试与常见错误
⚠️ 常见错误 1:模块路径不匹配。例如 settings 中写了
:feature:login,但磁盘上 feature/login 目录下缺少 build.gradle.kts,会报 Project with path ‘:feature:login’ could not be found。⚠️ 常见错误 2:Version Catalog 版本不一致。如果某个模块直接硬编码了版本号,而 catalog 中升级了该库,会导致运行时类冲突。解决办法:所有模块必须统一使用
libs.*,禁止裸写 implementation("xxx:1.0")。💡 调试技巧:在 Android Studio 的 Terminal 中执行
./gradlew projects 和 ./gradlew dependencies --configuration releaseRuntimeClasspath 可以快速查看模块树和依赖树。1.8 性能与稳定性优化
- 按需编译:利用 Gradle 的
--parallel参数、配置org.gradle.parallel=true并行构建。 - 模块化缓存:在 CI 中缓存
.gradle目录,避免重复下载依赖。 - 减少 module 间直接引用:feature 模块只应依赖 lib 模块,避免
feature A → feature B的横向耦合。 - 使用 BuildConfig 开关:在
buildConfigField中定义 module 级别的 debug/release 切面,避免 feature 模块运行时加载多余的 ViewModel 初始化代码。 - 检查依赖树:定期运行
./gradlew :app:dependencies确认没有重复或冲突的库版本。
✅ 完成后,你的项目结构应类似:
ViewModelModularApp/
├── app/
├── feature/
│ ├── login/
│ └── home/
├── lib/
│ ├── core/
│ ├── data/
│ ├── network/
│ └── test-utils/
└── gradle/
└── libs.versions.toml