说到 Gradle 编译,相信每个 Android 开发者都或多或少曾经被坑过。因为gradle依赖的仓库都在国外,而国内访问国外网络都情况大家也都懂得。我司的情况就更严重了,20 多个内部依赖,50 多个三方依赖。然后光 root 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。