IDEA里gradle如何使用

来先看一下在gradle里面长什么样子

idea java gradle 引入依赖 idea引入gradle项目_jar

文件

Value

.gradle

.gradle文件夹是编译后生成的,gradle的相关支持文件

.idea

IntelliJ IDEA的相关文件

build

构建生成物,存放项目构建中生成的class和jar包

src

Gradle 根工程配置文件,这是 Project 下的 build.gradle

build.gradle

gradle的构建配置,相当于Maven的pom.xml

GradleLearn.iml

IntelliJ IDEA的项目文件

gradlew

Linux、Mac 平台下,用于执行 Gralde 命令的包装器脚本

gradlew.bat

Windows 平台下,用于执行 Gralde 命令的包装器脚本

plugins {    //插件
	    id 'java'
	}
	
	group 'com.test'//
	version '1.0.1'//
	
	//指定jdk jre版本
    sourceCompatibility = 1.8 
    targetCompatibility = 1.8 
	
	配置工程的仓库地址
	repositories {
	    mavenCentral()
	}
	
	//配置工程的"插件"依赖地址
	//为应用程序添加第三方库依赖
	dependencies {
	    testCompile group: 'junit', name: 'junit', version: '4.12'
	}

对于Gradle来说,情形与Maven相似;同样需要先到https://www.gradle.org网站上先将Gradle二进制压缩包下载到本地,然后解压缩,再配置相应的环境变量,方可执行正常的项目构建工作。不过,除此之外,Gradle还提供了另外一种对于使用者更加友好的方式,使得使用者在将项目拉取到本地后,无需手工下载任何Gradle压缩包,只需通过一条简单的命令即可自动完成所需工具包的下载、配置与管理工作,同时还能够确保所下载的Gradle包的版本与项目所需的Gradle版本完全一致,规避了因软件版本的不同而导致的构建可能失败的结果。这种方式即是本文所要介绍的gradlew,即Gradle Wrapper。

gradle-wrapper.jar

这是gradlew执行构建时所依赖的jar包。值得注意的是,一般我们在使用Maven或是Gradle进行项目构建时,项目所依赖的jar包是不需要纳入版本控制系统中的,因为在执行构建时,这些依赖会被自动下载到本地(通过中央仓库、第三方仓库或是私服);但如果使用了gradle wrapper,那么这个gradle-wrapper.jar则是必须要纳入到版本控制系统中的,因为这是其他用户执行gradlew命令进行项目构建时所必须的。

gradle-wrapper.properties

gradle下载地址:https://gradle.org/releases/

distributionBase=GRADLE_USER_HOME
	distributionPath=wrapper/dists
	zipStoreBase=GRADLE_USER_HOME
	zipStorePath=wrapper/dists
	distributionUrl=https\://services.gradle.org/distributions/gradle--6.4.1-all.zip

distributionUrl

distributionUrl 是要下载的 gradle 的地址,使用哪个版本的 gradle,就在这里修改。
gradle 有 3 种版本:
gradle-xx-all.zip 是完整版,包含了各种二进制文件,源代码文件,和离线的文档。例如:https://services.gradle.org/distributions/gradle-6.4.1-all.zip
gradle-xx-bin.zip 是二进制版,只包含了二进制文件(可执行文件),没有文档和源代码。例如:https://services.gradle.org/distributions/gradle-6.4.1-bin.zip
gradle-xx-src.zip 是源码版,只包含了 Gradle 源代码,不能用来编译你的工程。例如:https://services.gradle.org/distributions/gradle-6.4.1-src.zip

其他4个属性

  • zipStoreBase和zipStorePath组合在一起,是下载的6.4.1-all.zip所存放的位置。
    zipStorePath是zipStoreBase指定的目录下的子目录。
  • distributionBase和distributionPath组合在一起,是解压6.4.1-all.zip之后的文件的存放位置。
    distributionPath是distributionBase指定的目录下的子目录。
    下载位置可以和解压位置不一样。
  • zipStoreBase和distributionBase有两种取值:GRADLE_USER_HOME和PROJECT。
    其中,GRADLE_USER_HOME表示用户目录。
    在windows下是%USERPROFILE%/.gradle,例如C:\Users<user_name>.gradle\。
    在linux下是$HOME/.gradle,例如~/.gradle。
    PROJECT表示工程的当前目录,即gradlew所在的目录。

具体流程

  1. 去 https://services.gradle.org/distributions/gradle-6.4.1-all.zip 下载gradle的6.4.1-all.版本
  2. 下载的gradle-6.4.1-all.zip存放到C:\Users<user_name>.gradle\wrapper\dists目录中
    (具体还有2级目录,即全路径为C:\Users<user_name>.gradle\wrapper\dists\gradle-3.1-bin<url-hash>\,gradle-3.1-bin目录是根据下载的gradle的文件名来定的,目录名是根据distribution url路径字符串计算md5值得来的,具体参考PathAssembler.java中的rootDirName()和getHash(),PathAssembler.java的位置见本文最后的参考路径)
  3. 解压gradle-3.1-bin.zip,将解压后的文件存放到C:\Users<user_name>.gradle\wrapper\dists中(同上)
  4. 先将下载到zipStoreBase和zipStorePath指定的位置,即gradlew所在目录的wrapper/dists目录下,即D:\gradle_env\wrapper\dists\gradle-3.3-bin\37bujujhbsnkqrb1fi6n3qirfu\gradle-3.3-bin.zip。
    注意:这里的gradle-3.3-bin\37bujujhbsnkqrb1fi6n3qirfu就是上面提到的2级目录
  5. 然后解压到distributionBase和distributionPath指定的位置,即user_home目录的wrapper/dists目录下,在我的电脑中位置:C:\Users\galian.gradle \wrapper\dists\gradle-3.3-bin\37bujujhbsnkqrb1fi6n3qirfu
    注意:这里的gradle-3.3-bin\37bujujhbsnkqrb1fi6n3qirfu就是上面提到的2级目录

gradlew与gradlew.bat

Gradle Wrapper是通过一个命令来完成这一切的工作。实际上,这个命令在*nix系统上就是一个shell脚本,在Windows系统上则是一个批处理文件bat。接下来,我们就来看看gradlew是如何配置与工作的。

gradle和gradlew的区别

gradlew就是对gradle的包装和配置,gradlew是gradle Wrapper,Wrapper的意思就是包装
因为不是每个人的电脑中都安装了gradle,也不一定安装的版本是要编译项目需要的版本,那么gradlew里面就配置要需要的gradle版本。
然后用户只需要运行gradlew就可以按照配置下载对应的gradle到项目的目录中,仅仅给项目本身用,然后就是clean、build等操作
此时我们就用gradlew clean这个命令,其实内部调用的是本项目中的gradle来执行的,所以就相当于进行了一次包装

settings.gradle

gradle插件引入dependency-management会做自动做一件核心事情:
引入org.springframework.boot:spring-boot-dependencies:SPRING_BOOT_VERSION
pring-boot-dependencies中维护了spring boot生态下的bom数据

plugins {
	    id "org.springframework.boot" version "2.1.4.RELEASE"
	    id "io.spring.dependency-management" version "1.0.6.RELEASE"
	}

gradle和maven有什么用

Gradle是一款高效易用的项目管理工具,于2012年基于Ant和Maven产生,并且弥补了Ant和Maven的不足,并且具备一些更高效的特点。它使用一种基于groovey的特定领域语言(DSL)来声明项目设置,抛弃了xml的各种繁琐配置。当前其支持的语言限于Java、Groovy、Kotlin和Scala,计划未来将支持更多的语言。

Maven同样也是一款高效易用的项目管理工具,主要的功能:
  1.依赖管理系统。
  2.多模块构建。
  3.一致的项目结构。
  4.一致的构建模型。
  5.插件机制。
  
Gradle和Maven都是项目自动构建工具,编译源代码只是整个过程的一个方面,更重要的是,你要把你的软件发布到生产环境中来产生商业价值,所以,你要运行测试,构建分布、分析代码质量、甚至为不同目标环境提供不同版本,然后部署。整个过程进行自动化操作是很有必要的。
整个过程可以分成以下几个步骤:

  • 编译源代码
  • 运行单元测试和集成测试
  • 执行静态代码分析、生成分析报告
  • 创建发布版本
  • 部署到目标环境
  • 部署传递过程
  • 执行冒烟测试和自动功能测试

基础配置信息
maven使用.pom文件,基于XML,gradle使用.gradle文件。
Maven可以用groupId、artifactId、version组成的Coordination(坐标)唯一标识一个依赖,
基于Groovy,gradle去掉maven中需要固定配置的groupId,artfactId,package等基本参数,通过 apply plugin: ‘java’,apply plugin: 'war’来表示打包方式,也提供sourceCompatibility,version等一些实用的标签。
Maven和Gradle对依赖项的审视也有所不同。在Maven中,一个依赖项有6种scope,分别是compile、provided、runtime、test、system、import。其中compile为默认。
gradle将其简化为4种,compile、runtime、testCompile、testRuntime。

scope

Value

compile

默认就是compile,编译、测试、运行都有效。

provided

编译和测试时有效

runtime

测试、运行时有效

test

测试时有效

system

编译、测试、运行都有效:但局限性大,不可移植(与本机系统相关联)

import

导入的范围:只存在于标签中表示从其他pom导入dependency配置

gradle升级到3.0之后,新增了 implementation, 而compile 方式被标记为了deprecated, compile 在3.0之后仍然可以使用,但是 gradle 官方说会在 gradle 后续的某次重要升级后变为不可用.

scope

Value

implementation

与compile对应,会添加依赖到编译路径,并且会将依赖打包到输出(aar或apk),但是在编译时不会将依赖的实现暴露给其他module,也就是只有在运行时其他module才能访问这个依赖中的实现。使用这个配置,可以显著提升构建时间,因为它可以减少重新编译的module的数量。建议,尽量使用这个依赖配置。

api

与compile对应,功能完全一样,会添加依赖到编译路径,并且会将依赖打包到输出(aar或apk),与implementation不同,这个依赖可以传递,其他module无论在编译时和运行时都可以访问这个依赖的实现,也就是会泄漏一些不应该不使用的实现。举个例子,A依赖B,B依赖C,如果都是使用api配置的话,A可以直接使用C中的类(编译时和运行时),而如果是使用implementation配置的话,在编译时,A是无法访问C中的类的。

compileOnly

与provided对应,Gradle把依赖加到编译路径,编译时使用,不会打包到输出(aar或apk)。这可以减少输出的体积,在只在编译时需要,在运行时可选的情况,很有用。

runtimeOnly

与apk对应,gradle添加依赖只打包到APK,运行时使用,但不会添加到编译路径。这个没有使用过。

annotationProcessor

与compile对应,用于注解处理器的依赖配置,这个没用过。

依赖管理
Gradle的jar包管理支持maven下Repository方式,也支持Ant的Ivy方式,由于maven的Repository已经非常成熟,gradle在兼容Repository做得非常方便,定义maven的repository:

mavenLocal() :maven 本地库
mavenCentral() : maven 远程库
mavenRepo urls: 自定义库路径
Maven:
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.7</version> 
    <scope>test</scope>
  </dependency>
Gradle:
  dependencies {    testCompile group:'junit', name: 'junit', version '4.11'}
或者
  dependencies {    testCompile 'junit:junit:4.11'    }

如果需要引用自己lib目录下jar包,maven需要在每个依赖加上 和标签或者在plugin里单独增加编译路径。而Gradle只需要加上

compile fileTree(dir: 'libs', include: '*.jar'),在多个路径下时:
jarTree = fileTree(dir: 'libs', include: '*.jar')
rootTree = new File(rootProject.rootDir, 'libs').getAbsolutePath()
jarTree += fileTree(dir: rootTree, include: '*.jar')
compile jarTree

在依赖相关的命令行方面,gradle与maven比较相似,maven常用的分析依赖命令包括:

mvn dependency:analyz查看依赖;
mvn dependency:tree 查看项目直接和传递依赖; 
mvn help:effective-pom查看有效的pom;

在gradle中使用gradle dependencies 可以查看项目中包的依赖关系。加上-configuration来查看指定阶段的依赖情况,还可以-dependency来查看指定jar的依赖情况。

<properties>
        <kaptcha.version>2.3</kaptcha.version>
    </properties>
<dependencies>
        <dependency>
            <groupId>com.google.code.kaptcha</groupId>
            <artifactId>kaptcha</artifactId>
            <version>${kaptcha.version}</version>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
dependencies {
    compile('org.springframework:spring-core:2.5.6')
    compile('org.springframework:spring-beans:2.5.6')
    compile('org.springframework:spring-context:2.5.6')
    compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')
    testCompile('junit:junit:4.7')
}

基本方式

implementation group: 'xx.xxx', name: 'xxxx', version: version
implementation group: 'com.example.android', name: 'app-magic', version: '12.3'
或者
implementation 'com.example.android:app-magic:12.3'

本地library模块依赖

implementation project(":mylibrary")

加载本地jar包

implementation files('/ss/sss/xxx.jar')

加载本地某个目录下的所有jar包

implementation fileTree(dir:'F:\\work\\FixBug\\lib',include:['*.jar'])

implementation fileTree(dir: 'libs', include: ['*.jar'])
这种依赖方式是依赖工程中的 module_name/libs/目录下的Jar文件(注意Gradle的路径是相对于build.gradle文件来读取的,所以上面是这样的相对路径)

排除传递依赖中的某些依赖

compile (group: 'xx.xx', name: 'zzz', version: version){
        exclude group: 'io.netty', module: 'netty-common'
    }

全局配置排除

configurations {
    compile.exclude module: 'cglib'
    //全局排除原有的tnet jar包与so包分离的配置,统一使用aar包中的内容
    all*.exclude group: 'com.taobao.android', module: 'tnet-jni'
    all*.exclude group: 'com.taobao.android', module: 'tnet-so'
}

禁用依赖传递

compile('com.zhyea:ar4j:1.0') {
    transitive = false
}

configurations.all {
    transitive = false
}

还可以在单个依赖项中使用@jar标识符忽略传递依赖:

compile 'com.zhyea:ar4j:1.0@jar'

强制使用某个版本
如果某个依赖项是必需的,而又存在依赖冲突时,此时没必要逐个进行排除,可以使用force属性标识需要进行依赖统一。当然这也是可以全局配置的:

compile('com.zhyea:ar4j:1.0') {
    force = true
}

configurations.all {
    resolutionStrategy {
        force 'org.hamcrest:hamcrest-core:1.3'
    }
}

1.执行 gradle wrapper 将会生成一些文件:

assemble: 编译
build:编译并执行测试
clean:删除build目录
jar: 生成jar包
test:执行单元测试

构建命令
清理命令

gradle clean

构建打包命令

gradle clean build

编译时跳过测试,使用-x,-x参数用来排除不需要执行的任务

gradle clean build -x test