複製 init.gradle.kts 文件到 Windows 的 %USERPROFILE%/.gradle 或者 Linux 的 ~/.gradle 目錄下。也可以直接複製文末的代碼為 init.gradle.kts。 Gradle 不支持鏡像源的直接設置,只能通過 maven() 方法設置一個新 ...
複製 init.gradle.kts 文件到 Windows 的 %USERPROFILE%/.gradle
或者 Linux 的 ~/.gradle
目錄下。也可以直接複製文末的代碼為 init.gradle.kts
。
Gradle 不支持鏡像源的直接設置,只能通過 maven() 方法設置一個新的 Maven 倉庫地址。
在 init.gradle 中調用 maven() 會導致鏡像倉庫排在上游倉庫之後,會導致Gradle 優先使用上游倉庫。如果直接刪除上游倉庫又會出現新的問題。Maven 鏡像源和上游倉庫並不是完全實時同步的,可能會缺失某些文件,特別是一些剛發佈的包。所以上游倉庫必須保留並且需要排在鏡像倉庫之後。
在使用過程中發現阿裡雲的 Maven 鏡像源仍然會出現找不到文件的錯誤。排查之後發現阿裡雲鏡像源的某個包竟然只有 POM 文件而沒有 JAR 文件。在這種情況下 Gradle 找到了 POM 文件就會僅使用阿裡雲鏡像源,然後找不到 JAR 文件報錯,而不會繼續使用上游倉庫。查閱 Gradle 文檔之後,發現有個 artifactUrls() 方法可以設置 Maven 倉庫的除 POM 文件之外的其他文件下載地址。這樣就可以通過在鏡像倉庫中將上游倉庫地址設置為Artifact URL解決這個問題。
普通的 Java 或 Kotlin 項目預設是在 build.gradle 里設置 Maven 倉庫地址,所以在 init.gradle 里需要在 allprojects
代碼塊中設置鏡像源。而 Android 項目預設都是在 settings.gradle 的 pluginManagement
和 dependencyResolutionManagement
代碼塊中設置 Maven 倉庫地址。僅在 allprojects
中設置鏡像源沒有用。所以還需要在 settingsEvaluated
代碼塊中進行設置。
一些舊的項目在添加 Google Maven 倉庫時,直接使用 maven("https://maven.google.com") 而不使用 google() 方法。構建項目時會一直卡在 Building 的狀態,並且沒有任何提示。maven.google.com
這個功能變數名稱在國內是 ping 不通的。而如果使用 google() 方法,Gradle 會使用 "https://dl.google.com/dl/android/maven2",這個鏈接在國內可以直連。所以需要將上游 Google 倉庫的 "https://maven.google.com" 替換為 "https://dl.google.com/dl/android/maven2"。
解決一系列問題之後,最終的 init.gradle 完成了。Gradle 同時支持 Groovy DSL(.gradle) 和 Kotlin DSL(.gradle.kts)。我選擇後者編寫 init.gradle.kts。由於 Gradle 直接兩種 DSL 語言的混用,所以如果之後構建 Groovy DSL 形式的 Gradle 項目,也不需要額外再編寫 init.gradle。
// https://gist.github.com/mkckr0/97ec5b0d99feede4c19ee6f905d5e722
val repoMirrorMap = mapOf(
"https://repo.maven.apache.org/maven2" to "https://maven.aliyun.com/repository/central",
"https://dl.google.com/dl/android/maven2" to "https://maven.aliyun.com/repository/google",
"https://plugins.gradle.org/m2" to "https://maven.aliyun.com/repository/gradle-plugin",
"https://jcenter.bintray.com" to "https://maven.aliyun.com/repository/jcenter",
)
val repoReplaceMap = mapOf(
"https://maven.google.com" to "https://dl.google.com/dl/android/maven2"
)
fun RepositoryHandler.setMirrors() {
all {
if (this is MavenArtifactRepository && !name.endsWith("Origin")) {
val originName = name
var originUrl = url.toString().trimEnd('/')
// do replace
repoReplaceMap[originUrl]?.let { newUrl ->
originUrl = newUrl
setUrl(originUrl)
}
// do mirror
repoMirrorMap[originUrl]?.let { newUrl ->
// replace into mirror repo
setUrl(newUrl)
// add origin repo to find missing jars
artifactUrls(originUrl)
// keep origin repo to find missing POM
maven(originUrl) { name = "$originName Origin" }
}
}
}
printRepos()
}
fun RepositoryHandler.printRepos() {
all {
if (this is MavenArtifactRepository) {
println("Maven Repo: name=\"$name\", url=$url, artifacts=${artifactUrls}")
}
}
}
settingsEvaluated {
pluginManagement {
repositories {
setMirrors()
}
}
dependencyResolutionManagement {
@Suppress("UnstableApiUsage")
repositories {
setMirrors()
}
}
}
allprojects {
buildscript {
repositories {
setMirrors()
}
}
repositories {
setMirrors()
}
}
本文來自博客園,作者:mkckr0,轉載請註明原文鏈接:https://www.cnblogs.com/mkckr0/p/17714374.html