第3章 现有缓存配置盘点:settings.gradle 中 buildCache 配置、local cache 和 remote cache 的启用状态、缓存目录结构
在升级 AGP 之前,必须全面盘点项目当前的构建缓存配置。很多缓存兼容性问题源于对现有配置的误判:不清楚本地缓存是否启用、远程缓存的认证方式、缓存目录是否被自定义迁移。本章以实际项目为蓝本,逐一对照 settings.gradle、Gradle 缓存目录、AGP 中间产物目录,建立“缓存配置快照”,为后续兼容性评估提供基准。
3.1 为什么要先盘点缓存配置?
- 基线缺失:不同团队的 local/remote cache 启用策略差异大,AGP 升级可能改变缓存 key 计算规则,导致之前所有的缓存全部失效。
- 性能回退:升级后若缓存配置被错误覆盖,全量构建时间可能从 2 分钟变成 30 分钟,必须提前记录 “启用状态 + 目录位置 + 权限策略”。
- 调试前提:只有知道“当前缓存是否命中”,才能判断升级后是否出现缓存穿透或错误缓存命中。
settings.gradle 做一次 git stash,或者在分支上保留原始配置截图,以便回退时快速复原。3.2 查询 settings.gradle 中的 buildCache 配置块
构建缓存配置位于 settings.gradle(或 settings.gradle.kts)的 buildCache 闭包内。以下是一个典型的多模块项目配置示例:
// settings.gradle(Groovy DSL)
buildCache {
local {
enabled = true
directory = new File(rootDir, '.gradle-build-cache')
removeUnusedEntriesAfterDays = 7
}
remote(HttpBuildCache) {
enabled = true
url = 'https://cache.team.company.com/cache/'
push = false
credentials {
username = 'build-cache-user'
password = System.getenv('GRADLE_CACHE_PASSWORD') ?: ''
}
}
}
| 配置项 | 含义 | 升级要关注的关键点 |
|---|---|---|
local.enabled | 是否启用本地构建缓存 | AGP 8.x 开始不再依赖 Gradle 本地缓存管理部分内部任务,需确认。 |
local.directory | 本地缓存目录 | 默认在 ~/.gradle/caches/build-cache-1,自定义路径可能被忽略或权限问题。 |
remote.push | 是否允许向远程推送缓存 | 升级后若 key 算法变化,推送失败可能导致远程缓存污染。 |
remote.credentials | 远程缓存认证方式 | 升级 Gradle 后 HTTP 认证头格式可能变更,需测试。 |
3.3 本地缓存启用状态与目录结构
本地缓存默认路径为 ~/.gradle/caches/build-cache-1,其中存储以 SHA-1 命名的缓存文件。可通过命令行快速检测启用状态与目录内容:
# 检查本地缓存目录是否存在,并根据文件数量判断是否被使用
ls -la ~/.gradle/caches/build-cache-1/ | wc -l
# 用 Gradle 构建任务验证缓存是否被写入(需要先 clean 然后 build)
cd /path/to/your/project
./gradlew clean assembleDebug --build-cache --info | grep "Stored entry in build cache"
local.directory 也可以自定义到项目内,例如 .gradle-build-cache。这种配置在 CI 常被用,但升级后要注意build-cache-1 目录名可能被 Gradle 内部硬编码(Gradle 7.6.3+ 支持自定义,但旧版本可能忽略)。
3.4 远程缓存启用状态与常见问题
远程缓存配置在 buildCache.remote(HttpBuildCache) 中。启用状态判断:
- 查看
settings.gradle中remote.enabled是否为true。 - 确认
url指向的服务是否可达,通过 curl 测试:curl -I https://cache.team.company.com/cache/ - 查看构建日志中是否出现
Remote build cache is available或Remote cache: no entries found等字样。
GRADLE_CACHE_PASSWORD → GRADLE_CACHE_)。3.5 缓存目录结构详解
Gradle 构建缓存目录(build-cache-1)内部是扁平化存储,以缓存 key 的 SHA-1 前两位作为子目录,共 256 个子文件夹。结构如下:
~/.gradle/caches/build-cache-1/
├── 00/ (SHA-1 前缀 "00")
│ ├── abcd1234... (完整缓存条目)
│ └── ...
├── 01/
├── ...
├── ff/
└── gc.properties // 缓存 GC 配置
每个缓存条目是一个 .tar 或 .tar.gz 包,包含构建产物(如 .class、.ap_、.dex)。AGP 的增量编译缓存(build/intermediates/)不在此目录下,而是项目自己的 build 目录中,两者互不干扰但都影响构建速度。
3.6 构建日志分析:验证缓存配置是否生效
使用 --info 级别查看缓存存储与加载:
./gradlew assembleDebug --build-cache --info 2>&1 | grep -E "(Store|Load|cache)"
典型输出分析:
2025-03-15T10:22:33.124+0800 [INFO] [org.gradle.caching.internal.DefaultBuildCacheController] Remote build cache is available.
2025-03-15T10:22:33.124+0800 [INFO] [org.gradle.caching.internal.DefaultBuildCacheController] Stored entry in build cache with key 'base64-encoded-key'
如果没有出现 Stored entry 或 Loaded entry,说明缓存配置未生效或从未命中。
3.7 常见缓存配置兼容性问题(盘点阶段)
| 场景 | 现象 | 原因 |
|---|---|---|
| local.directory 使用了相对路径 | 构建后缓存目录未创建 | Gradle 7.x 对相对路径解析方式与 8.x 不同,导致目录无效 |
| remote.url 包含尾随空格 | 远程缓存永远超时或 404 | 旧版 Gradle 会自动 trim,新版可能不会 |
| 同时启用 local 和 remote,但 remote.push=false | 本地缓存频繁被清除 | 默认 remote.push=false 时,本地缓存会被当作唯一来源,GC 策略激进 |
| 多个项目共享同一远程缓存,但 Gradle 版本不同 | 缓存条目无法加载 | 缓存 key 中编码了 Gradle 版本号,跨版本不兼容 |
3.8 调试方案与验证步骤
- 备份当前配置:复制
settings.gradle到settings.gradle.bak,并记录所有缓存相关环境变量。 - 执行基准构建:先
clean,再assembleDebug --build-cache,记录总耗时。 - 检查本地缓存目录:
ls -la ~/.gradle/caches/build-cache-1/ | head -20,确认有文件生成。 - 触发第二次构建(不 clean):
assembleDebug --build-cache,若时间大幅缩短,说明本地缓存生效。 - 查看构建报告:
--build-cache --info输出中搜索from cache,确认有哪些任务使用了缓存。
3.9 性能优化提示(盘点后立即可做)
- 将本地缓存目录指向固态硬盘分区,减少 I/O 延迟。
- 设置
removeUnusedEntriesAfterDays = 30避免过早清理。 - 如果使用远程缓存,考虑在
local.directory中设置较大的磁盘配额(如 5GB),减少远程拉取次数。
3.10 当前缓存配置全局视图
下面的 SVG 图展示了从 settings.gradle 的 buildCache 配置到本地缓存目录、远程缓存服务器的映射关系,以及常见故障点(红色标记)。
3.11 验证清单
- ✅ 已记录
local.enabled与remote.enabled实际值。 - ✅ 已确认本地缓存目录存在且可读写。
- ✅ 已测试远程缓存 URL 从 CI 环境可用。
- ✅ 已执行基准构建并保存日志(包含
--info)。 - ✅ 已备份当前
settings.gradle至版本管理。