Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

android - Why there are multiple copies for the same version of gradle

I have an android studio project, with the file gradle/wrapper/gradle-wrapper.properties configured as following.

#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-2.2.1-all.zip

And I have the 2.2.1-all version installed in my home directory.

.gradle/wrapper/dists/gradle-2.2.1-all/c64ydeuardnfqctvr1gm30w53/gradle-2.2.1-all.zip

When I invoke ./gradlew command to build the project. I should use the gradle-2.2.1-all.zip to build.

But it doesn't, it will download another gradle even for the same version instead. So, there are two gradles for the version 2.2.1-all. Because my internet connection is very slow, it takes too long.

.gradle/wrapper/dists/gradle-2.2.1-all/c64ydeuardnfqctvr1gm30w53/gradle-2.2.1-all.zip
.gradle/wrapper/dists/gradle-2.2.1-all/6dibv5rcnnqlfbq9klf8imrndn/gradle-2.2.1-all.zip

It's very annoying since it has to download a new one for the same version very time I invoke the command to build my project.

Why the gradle build system couldn't pick the installed one?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem occurred is because the hash policy for the download url is different between studio's gradle-wrapper.jar and latest gradle-wrapper.jar.

The gradle-wrapper.jar under my Android app directory (I guess it's copied from android-sdk-macosx/tools/templates/gradle/wrapper/gradle/wrapper/gradle-wrapper.jar) use the following method to calculate hash for the download url.

// PathAssembler.java
private String getMd5Hash(String string) {
    try {
        MessageDigest e = MessageDigest.getInstance("MD5");
        byte[] bytes = string.getBytes();
        e.update(bytes);
        return (new BigInteger(1, e.digest())).toString(32);
    } catch (Exception var4) {
        throw new RuntimeException("Could not hash input string.", var4);
    }
}

But the latest gradle-wrapper.jar use the following method to do. The radix change from 32 to 36.

private String getHash(String string) {
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        byte[] bytes = string.getBytes();
        messageDigest.update(bytes);
        return new BigInteger(1, messageDigest.digest()).toString(36);
    } catch (Exception e) {
        throw new RuntimeException("Could not hash input string.", e);
    }
}

The magic string I found in the directory name is the md5 hash string of the download url.

For version 2.10, there is a directory name

.gradle/wrapper/dists/gradle-2.10-all/a4w5fzrkeut1ox71xslb49gst

And the a4w5fzrkeut1ox71xslb49gst is hashed from the download url.

try {
    MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    messageDigest.update("https://services.gradle.org/distributions/gradle-2.10-all.zip".getBytes());
    System.out.println(new BigInteger(1, messageDigest.digest()).toString(36));
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
}

By using the same hash method (use the same gradle-wrapper.jar) for the same download url from gradle/wrapper/gradle-wrapper.properties, there won't be multiple downloads for the same version of gradle.

This issue only exist between android studio project and other gradle project.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...