gradle wrapper与gradle缓存简介

2019-12-24 Views gradle android

Gradle在Android工程编译中起着重要的作用,但对于大多数Android开发者而言Gradle是一个熟悉的陌生人,因此多了解一些Gradle内部细节可以有助我们平时的开发。由于近期参与了扎克项目的研发,对于gradle有一些学习。这篇文章将会从gradle wrapper和.gradle两个方面进行简述。

gradle wrapper

Gradle Wrapper称为Gradle包装器,是对Gradle的一层包装。为什么需要Gradle Wrapper呢?比如在一个开发团队中,如果每进来一个成员,都需要在计算机中安装Gradle,这个时候运行Gradle的环境和版本就会对构建结果带来不确定性。针对这个问题,Gradle提供了一个解决方案,那就是Gradle Wrapper,它是一个脚本,可以在计算机没有安装Gradle的情况下运行Gradle构建,并且能够指定Gradle的版本,开发人员可以快速启动并运行Gradle项目,而不必手动安装,这样就标准化了项目,从而提高了开发效率。AS在新建项目时会自带Gradle Wrapper,这也是我们很少去单独去下载安装Gradle的原因。Gradle Wrapper的工作流程如下图所示。

Gradle Wrapper在一个工程中的主要文件结构如下:

├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat

gradle-wrapper.jar:包含Gradle运行时的逻辑代码。

gradle-wrapper.properties:负责配置包装器运行时行为的属性文件,用来配置使用哪个版本的Gradle等属性。

gradlew:*nux平台下,用于执行Gralde命令的包装器脚本。

gradlew.bat:Windows平台下,用于执行Gralde命令的包装器脚本。

gradle-wrapper.properties

gradle-wrapper.properties是Gradle Wrapper的属性文件,用来配置Gradle Wrapper,项目中的gradle-wrapper.properties内容如下。

//Gradle解压后存储的主目录
distributionBase=GRADLE_USER_HOME 

//distributionBase指定目录的子目录。distributionBase+distributionPath就是Gradle解压后的存放位置
distributionPath=wrapper/dists 

//Gradle压缩包存储主目录
zipStoreBase=GRADLE_USER_HOME 

//zipStoreBase指定目录的子目录。zipStoreBase+zipStorePath就是Gradle压缩包的存放位置
zipStorePath=wrapper/dists 

//Gradle文件的下载地址
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

其中distributionBase解压位置和zipStoreBase下载位置可以不一样。

zipStoreBase和distributionBase有两种取值:GRADLE_USER_HOME 和 PROJECT。

GRADLE_USER_HOME
表示gradle用户目录。默认在系统用户目录下。也可以在环境变量中指定位置
在windows下是%USERPROFILE%/.gradle,例如C:\Users\<user_name>\.gradle\。

在linux下是$HOME/.gradle,例如~/.gradle。

PROJECT
表示工程的当前目录,即gradlew所在的目录。

最后我们可以在电脑中找到gradle源文件所在路径

路径命名规则是
/wrapper/dists/{gradle-version}-{all/bin}/{hash value}/{gradle-version}

其中要关注的一点是gradle解压后文件路径前的以hash value命名的文件夹。它的生成规则如下:

private String getHash(String string) {
    try {
        //计算传入string的MD5值(这个string是gradle各个版本的下载链接)
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        byte[] bytes = string.getBytes();
        messageDigest.update(bytes);
        //转化成一个BigInteger,再取Base36值
        return new BigInteger(1, messageDigest.digest()).toString(36);
    } catch (Exception e) {
        throw new RuntimeException("Could not hash input string.", e);
    }
}

源码:https://github.com/gradle/gradle/blob/master/subprojects/wrapper/src/main/java/org/gradle/wrapper/PathAssembler.java

另外在{gradle-version}的同级目录下有xx.lck文件和xx.ok文件,以及未展示的.part文件

  • .lck文件:下载gradle文件前需要lock住这个文件,保证在某个时刻只能有一个使用者在使用该gradle库
  • .part文件:下载时会先下载到一个part文件,等下载完成了,就重命名为最终的文件名,这里有个细节,每次下载都会删除掉之前的part文件,也就是说这里并不支持断点下载
  • .ok文件:用于表示该gradle库下载校验通过,这个gradle库可以被正常使用

.gradle目录

由上文可知,.gradle目录是gradle全局配置的文件夹,其目录下主要有caches 、daemon 、native 、wrapper 等目录,如下所示:

caches	gradle下载的缓存目录
daemon	daemon日志目录
native	gradle平台相关目录
workers     空目录
wrapper     gradle源文件目录

cache目录

cache目录是gradle下载AAR的全局缓存目录,一般在构建项目时引用的aar,会先检查是否有本地缓存。
有的话会直接使用本地缓存,没有才会根据gradle文件中记录的maven仓库顺序下载。

//目录 说明
4.6	特定于版本的缓存(例如,支持增量构建)
5.1	特定于版本的缓存(例如,支持增量构建)
jars-3	共享缓存,一般是jar文件的缓存目录
modules-2	共享缓存,一般为下载AAR缓存目录
transforms-1	下载AAR缓存目录
transforms-2	AAR解压后的缓存目录

modules-2目录

modules-2记录都是AAR缓存目录,规则命名如下:

{group}/{name}/version/{shanum1}/${package-version}.aar
{group}/{name}/version/{shanum2}/${package-version}.pom
{group}/{name}/version/{shanum3}/${package-version}.jar
//对于aar目录前的shanum,是对于整个文件计算sha1获取到的(长度40位),另有一个特点是首位若是0的话会被省略

transforms-1目录

内部会有package-aware-r.txt文件,该文件记录了AAR中的资源文件名称。

transforms-2目录

该文件夹会有同名的bin文件同时存在,部分文件夹下是AAR文件解压后的产物。

缓存策略

从版本4.10开始,Gradle会自动清除其用户主目录。当Gradle守护程序停止或关闭时,清理将在后台运行。如果使用--no-daemon,它将在带有可视进度指示器的构建会话之后在前台运行。
定期(最多每24小时)应用以下清理策略:

  1. caches//检查特定版本中是否仍在使用它们。如果未被引用,则发布版本的缓存时间为30天,快照版本缓存时间为7天。
  2. 检查caches/(例如jars-*)中的共享缓存是否仍在使用中。如果没有Gradle版本仍在使用它们,则会将其删除。
  3. 当前caches/(例如jars-3或modules-2)中的当前Gradle版本使用的共享缓存中的文件将在上次访问时进行检查。根据是可以在本地重新创建文件,还是必须再次从远程存储库下载文件,将分别在不访问7天或30天后将其删除。

参考文章:

  • https://docs.gradle.org/current/userguide/directory_layout.html#dir:gradle_user_home
  • https://docs.gradle.org/current/userguide/gradle_wrapper.html
  • https://zhuanlan.zhihu.com/p/26473930

赏 支付宝扫码打赏 微信打赏

△