# Gradle

# gradle 设置镜像

在 gradle 的目录中建立 init.gradle.kts

fun RepositoryHandler.enableMirror() {
  all {
    if (this is MavenArtifactRepository) {
      val originalUrl = this.url.toString().removeSuffix("/")
      // logger.lifecycle(originalUrl)
      urlMappings[originalUrl]?.let {
        // logger.lifecycle("Repository[$url] is mirrored to $it")
        this.setUrl(it)
      }
    }
  }
}


val urlMappings = mapOf(
  "https://repo1.maven.org/maven2" to "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/",
  "https://repo.maven.apache.org/maven2" to "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/",
  "https://dl.google.com/dl/android/maven2" to "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/",
  "https://plugins.gradle.org/m2" to "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/"

)


gradle.allprojects {
  buildscript {
    repositories.enableMirror()
  }
  repositories.enableMirror()
}

gradle.beforeSettings {
  pluginManagement.repositories.enableMirror()
  dependencyResolutionManagement.repositories.enableMirror()
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 资源

# 概念

# buildscript、allprojects、subprojects 的 repositories 有什么区别

  • buildScript 块的 repositories 主要是为了 Gradle 脚本自身的执行,获取脚本依赖插件。也就是说,buildScript 是用来加载 Gradle 脚本自身需要使用的资源,可以声明的资源包括依赖项、第三方插件、maven 仓库地址等。
  • 根级别的 repositories 主要是为了当前项目提供所需依赖包,比如 log4j、spring-core 等依赖包可从 mavenCentral 仓库获得。
  • allprojects 块的 repositories 用于多项目构建,为所有项目提供共同的所需依赖包。而子项目可以配置自己的 repositories 以获取自己独需的依赖包。
  • subprojects 块的 repositories 用于配置这个项目的子项目。使用多模块项目时,不同模块之间有相同的配置,导致重复配置,可以将相同的部分抽取出来,使用配置注入的技术完成子项目的配置。根项目就像一个容器, subprojects 方法遍历这个容器的所有元素并且注入指定的配置。allprojects 是对所有 project 的配置,包括 Root Project。而 subprojects 是对所有 Child Project 的配置。

  • buildScript 块的 repositories 主要是为了 Gradle 脚本自身的执行,获取脚本依赖插件。我在写的一篇博客《尝试 Artifactory》中 Gradle 脚本需要 com.jfrog.artifactory 插件才能执行成功,而这个插件是从 URL 为https://plugins.gradle.org/m2/的Maven仓库获得。
  • 根级别的 repositories 主要是为了当前项目提供所需依赖包,比如 log4j、spring-core 等依赖包可从 mavenCentral 仓库获得。
  • allprojects 块的 repositories 用于多项目构建,为所有项目提供共同所需依赖包。而子项目可以配置自己的 repositories 以获取自己独需的依赖包。

# 常用指令

# 跳过测试

gradle build -x test
1

# io.spring.dependency-management 插件实现类 Maven 的依赖管理方式

# 引入插件

plugins {
  id "io.spring.dependency-management" version "1.0.8.RELEASE"
}
1
2
3

# 引入依赖


dependencyManagement {
    dependencies {
        dependency 'org.springframework:spring-core:4.0.3.RELEASE'
    }
}
1
2
3
4
5
6

或者

dependencyManagement {
    dependencies {
        dependency group:'org.springframework', name:'spring-core', version:'4.0.3.RELEASE'
    }
}
1
2
3
4
5
# 依赖管理

如果对于多个模块具有相同的 group 和 version 的依赖配置,你可以使用依赖集进行配置。这样你就只需要指定统一的 group 和 version,而依赖模块不需要再额外指定。如下所示:

dependencyManagement {
     dependencies {
          dependencySet(group:'org.slf4j', version: '1.7.7') {
               entry 'slf4j-api'
               entry 'slf4j-simple'
          }
     }
}
1
2
3
4
5
6
7
8
# 排除依赖
dependencyManagement {
    dependencies {
        dependency('org.springframework:spring-core:4.0.3.RELEASE') {
            exclude 'commons-logging:commons-logging'
        }
    }
}
1
2
3
4
5
6
7

也可以对依赖集的 entry 中进行排除:

dependencyManagement {
    dependencies {
        dependencySet(group:'org.springframework', version: '4.1.4.RELEASE') {
            entry('spring-core') {
                exclude group: 'commons-logging', name: 'commons-logging'
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
# 强制版本
compile('com.github.nanchen2251:CompressHelper:1.0.5'){
        force = true
}


configurations.all {
   resolutionStrategy {
       force 'com.github.nanchen2251:CompressHelper:1.0.5'
   }
}
1
2
3
4
5
6
7
8
9
10
# 传递依赖

在 Maven 仓库中,构件通过 POM(一种 XML 文件)来描述相关信息以及传递性依赖。Gradle 可以通过分析 该文件获取获取所以依赖以及依赖的依赖和依赖的依赖的依赖,为了更加直观的表述,可以通过下面的输出 结果了解。

可以看到,我们的项目依赖了 com.android.support-v4 包,然而 com.android.support-v4 包却依赖了一众 support 的全家桶,借助 Gradle 的传递性依赖特性,你无需再你的脚本中把这些依赖都声明一遍,你只需要简单的一行,Gradle 便会帮你将传递性依赖一起下载下来。


// 关闭一个包的依赖
compile('com.android.support:support-v4:23.1.1'){
        transitive = false
}

compile group:'log4j',name:'log4j',version:'1.2.17',transitive:false

compile 'com.android.support:support-v4:23.1.1'@jar

// 本局关闭依赖
configurations.all {
   transitive = false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 冲突管理
  1. 最近版本策略(默认):上例将忽略 b-1.1,而下载 b-1.2
  2. 冲突失败策略:发生冲突时,编译失败(有些新版本库并不兼容之前的,因此这个库可以让开发者主动作出选择)
  3. 强制指定版本策略:发生冲突时,使用开发者指定的版本
/* 冲突失败策略设置*/
configurations.all {
    resolutionStrategy {  failOnVersionConflict() }
}
/* 强制指定版本策略设置*/
dependencies {
    compile group:'b',name:'b',version:'1.1',force:true
}
1
2
3
4
5
6
7
8
# 动态依赖
dependencies {
    /* 选择1以上任意一个版本,这使发生版本冲突的几率变小*/
    compile group:'b',name:'b',version:'1.+'
    /* 选择最新的版本,避免直接指定版本号 */
    compile group:'a',name:'a',version:'latest.integration'
}
1
2
3
4
5
6
# 替换传递依赖的版本
compile group:'a',name:'a',version:'l.0' {
    dependencies 'b:b:1.1'
}
1
2
3

# 导入 Maven Bom

插件允许你导入已经存在的 Maven Bom 来使用其依赖的关系管理:

dependencyManagement {
     imports {
          mavenBom 'io.spring.platform:platform-bom:1.0.1.RELEASE'
     }
}

dependencies {
     compile 'org.springframework.integration:spring-integration-core'
}

1
2
3
4
5
6
7
8
9
10

# 查看依赖


# 'runtimeClasspath', 'runtimeElements', 'runtimeOnly'

gradle dependencies --configuration compileClasspath

gradle dependencies --info

1
2
3
4
5
6
7

# 设置全局变量

# 建立 config.gradle

ext {
    buildInfo = [
            version_code: 3,
            version_name: "3.0.0"
    ]
    android = [
            minSdkVersion   : 19,
            targetSdkVersion: 28
    ]
}
1
2
3
4
5
6
7
8
9
10

# 导入

// buildsystem 为文件所在的文件夹
apply from: 'buildsystem/config.gradle'
1
2

# 使用

defaultConfig {
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode rootProject.ext.buildInfo.version_code
        versionName rootProject.ext.buildInfo.version_name
}
1
2
3
4
5
6

# 在 gradle.properties 文件中配置

version_code=1
version_name=1.0.0
1
2

# 在 settings.gradle 中加入全局变量

gradle.ext.version_code=4
gradle.ext.version_name="4.0.0"
1
2