Gradle 缓存系统详解:dists 文件夹

1. Gradle用户目录结构

一般在我们电脑设备中,存在如下目录:

GRADLE_USER_HOME/wrapper/dists/

类似于这种:

这个目录通常包含了 Gradle 运行时所需要的各种文件,包括了下载的Gradle分发包。

2. dists文件夹的作用

dists 文件夹是 Gradle 分发包的缓存目录。它存储了通过 Gradle Wrapper 下载的所有 Gradle 版本。当团队成员在不同的项目中使用了不同的 Gradle 版本时,每个版本都会被下载并且存储在这个目录中,这样做的目的是:

  1. 避免重复下载:同一个版本的 Gradle只需要下载一次
  2. 多项目支持:允许不同项目中使用不同的Gradle 版本
  3. 快速切换:在项目之间切换快速使用所需的 Gradle 版本
3. Gradle 版本逻辑

经常下载 Gradle 的人会知道,我们可能存在很多版本 gradle-7.0.2-all, gradle-8.8-bin等等,我们可以在这个网站找到所有的 Gradle 版本: https://services.gradle.org/distributions/

如图:

存在多个不同文件夹(即不同版本)的原因,是因为:

  1. 不同项目的迭代需求:项目年限不同,Gradle 的版本也可能不同;
  2. 版本迭代:随着时间推移,项目更新 Gradle 版本;
  3. 尝试和测试:可能一个项目为了解决某些 bug,新增了不同版本的 Gradle

一般这些文件夹的命令会遵循以下特定的格式:

gradle-[版本号]-[分发类型]

例如:

  • gradle-7.0.2-all : Gradle 7.0.2版本的完整分发包(包含了文档和源码)
  • gradle-8.0-bin: Gradle 8.0 版本的二进制分发包(仅包含了允许所需的文件)
4. dists文件夹内部结构

我们进入任何一个版本的文件夹,都会看到如下类似的结构:

我们总结起来:

gradle-8.7-all/
  ├── [长哈希值]/                 # 唯一标识这个下载的哈希值
     ├── gradle-8.7/             # 解压后的Gradle分发包
     └── gradle-8.7-all.zip.ok   # 下载完成标记文件
     └── gradle-8.7-all.zip.lck  # 下载锁文件(可能不总是存在)

哈希值文件夹

这个长字符串文件夹名是根据distributionUrl和其他因素生成的唯一哈希值。它可以保证同一版本但从不同URL下载的Gradle分发包不会冲突,并且可以验证下载的完整性

解压后的Gradle目录

这个目录包含实际的Gradle程序文件,当运行./gradlew命令时,实际上是使用这个目录中的Gradle可执行文件。

.zip.ok文件

这是一个标记文件,表示ZIP文件已成功下载和验证。它的存在告诉Gradle Wrapper不需要重新下载这个版本。

.zip.lck 文件

是一个锁文件,主要有以下作用:

  1. 防止并发下载:确保同一时间只有一个进程在下载特定的 Gradle 分发包
  2. 防止损坏的文件下载:如果中断下载,锁文件可以表明下载未完成
  3. 支持多进程安全:在多个 Gradle 进程中同时运行时维护缓存一致性
5. 缓存机制的工作流程

当在项目中运行 ./gradlew时,会有以下事情发生:

  1. Wrapper 脚本读取 gradle-wrapper.properties中的distributionUrl
  2. 根据 URL 生成唯一的目标目录哈希
  3. 检查 GRADLE_USER_HOME/wrapper/dists/gradle-[版本]-[类型]/[哈希]/`是否存在
  4. 如果存在且存在.ok 文件,直接使用已有的Gradle 版本
  5. 如果不存在,下载指定版本,验证,解压,并创建.ok文件
  6. 使用解压后的Gradle执行请求任务

到这里了,我们来想想,为什么需要这么设计呢?这样设计有什么好处呢?

这种缓存设计有几个关键的优势:

  1. 资源节省:避免重复下载同一个版本;
  2. 搞笑切换:在不同的 Gradle 版本的项目之间快速切换
  3. 隔离性:每个版本都是完全独立的,不会相互干扰
  4. 安全性:通过哈希值和验证正确确保下载正确性
  5. 无需全局安装:不需要手动安装 Gradle,减少了环境配置的复杂性
6. 管理 dists目录

随着时间推移,这个目录可能会累积大量的Gradle版本,占用磁盘空间。以下是一些管理建议:

  1. 安全删除旧版本 删除不再使用的Gradle版本文件夹。如果之后某个项目需要这个版本,Wrapper会自动重新下载。

  2. 识别不再使用的版本 删除明显过旧且不再使用的版本

  3. 自动清理 Gradle 6.5之后引入了缓存自动过期机制,可以在 gradle.properties中配置:

    # 设置缓存保留7天
    org.gradle.caching.cleanup.strategy=DAYS
    org.gradle.caching.cleanup.duration=7
    
7. 开发场景
  1. 切换到新项目

    当从使用Gradle 7.4的项目切换到使用Gradle 8.2的新项目时:

    • 运行./gradlew时系统会检查dists目录

    • 如果已经有Gradle 8.2的缓存,直接使用

    • 如果没有,会下载并缓存Gradle 8.2,同时保留Gradle 7.4

  2. 项目Gradle版本升级

    当项目从Gradle 7.6升级到8.0时:

    • 更新gradle-wrapper.properties中的distributionUrl
    • 首次运行会下载并缓存Gradle 8.0
    • 原有的Gradle 7.6缓存保持不变,便于回滚
  3. 离线工作

    如果需要在没有网络连接的环境中工作:

    • 只要相应版本的Gradle已在dists目录中
    • 即使没有网络连接,也可以正常使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值