美文网首页程序猿的干货
Gradle 编译的那些坑

Gradle 编译的那些坑

作者: TonyLeee | 来源:发表于2019-01-24 19:48 被阅读8次

    说到 Gradle 编译,相信每个 Android 开发者都或多或少曾经被坑过。因为gradle依赖的仓库都在国外,而国内访问国外网络都情况大家也都懂得。我司的情况就更严重了,有四个内部仓库,20 多个内部库,50 多个外部库。gradle 文件里有这么多仓库:

    repositories {
           jcenter()
           mavenCentral()
           google()
           maven {
               url "http://127.0.0.1:8081/nexus/content/repositories/releases/"  // 127.0.0.1 代指内部 maven 仓库
           }
           maven {
               url "http://127.0.0.1:8081/nexus/content/repositories/central"
           }
           maven {
               url "http://127.0.0.1:8081/nexus/content/repositories/snapshots"
           }
           maven {
               url "http://127.0.0.1:8081/nexus/content/groups/public"
           }
           maven { url "https://jitpack.io" }
           maven {
               url "https://oss.sonatype.org/content/repositories/snapshots/"
           }
           mavenLocal()
    }
    

    每次拉一个新仓库下来,光 sync dependencies 就要好久。万一中间再遇到什么坑,那就有得搞了,有时候一两天都不一定能解决。本篇文章就是笔者总结的遇到的 gradle sync 中遇到的一些坑。

    先试试重启大法?

    重启试试? Invalidate Caches and Restart 了解一下?

    大坑:JCenter 被墙

    如果你最近突然发现 jcenter 上的东西一直拉不下来,那大概率是 jcenter 被墙了。
    解决方案:
    全局替换 jcenter 源到 aliyun mirror:

    ~/.gradle 目录下新建 init.gardle 文件,输入以下内容:

    gradle.projectsLoaded {
        rootProject.allprojects {
            buildscript {
                repositories {
                    def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
                    all { ArtifactRepository repo ->
                        if (repo instanceof MavenArtifactRepository) {
                            def url = repo.url.toString()
                            if (url.startsWith('https://repo1.maven.org/maven2')
                                || url.startsWith('https://jcenter.bintray.com/')) {
                                project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."
                                println("buildscript ${repo.url} replaced by $REPOSITORY_URL.")
                                remove repo
                            }
                        }
                    }
                    jcenter {
                        url REPOSITORY_URL
                    }
                }
            }
            repositories {
                def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
                all { ArtifactRepository repo ->
                    if (repo instanceof MavenArtifactRepository) {
                        def url = repo.url.toString()
                        if (url.startsWith('https://repo1.maven.org/maven2')
                            || url.startsWith('https://jcenter.bintray.com/')) {
                            project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."
                            println("allprojects ${repo.url} replaced by $REPOSITORY_URL.")
                            remove repo
                        }
                    }
                }
                jcenter {
                    url REPOSITORY_URL
                }
            }
        }
    }
    

    Gradle 缓存存放位置

    ~/.gradle/caches/modules-2/files-2.1 这个目录下可以找到你依赖的所有 gradle 库的包。

    明明有缓存,却提示一直拉不下来?

    之前我曾遇到过某两个库依赖一直无法拉下来的问题,遂从别人电脑的 cache 路径下 copy 过来对应目录,以为这样就能解决了。却发现 gradle sync 无论如何也无法重试,挂了代理,切换 offline mode... 都尝试未果。 后来经分析 Gradle 在每个项目的 .gradle 目录下生成了一份 hash 映射,对应每个版本一份。在第一次获取这个依赖库的时候生成,此后就一直根据这个 hash 查找。然而有个很坑爹的问题是,这个 hash 值在没台电脑下都不一致。而 gradle 在下载依赖时,只会根据依赖包命和版本号判断对应依赖是否已经存在在缓存中。所以就出了这个现象:明明缓存里有,但 gradle 编译就是找不到,然后又一直不会去下载。
    解决方案:
    删除工程目录下的 .gradle 目录和本地 ~/.gradle/caches/modules-2/files-2.1 下的所有文件,然后重启 AS 进行 sync。

    相关文章

      网友评论

        本文标题:Gradle 编译的那些坑

        本文链接:https://www.haomeiwen.com/subject/yqdmottx.html