Gradle基础

来源:互联网 发布:毛新宇是不是装的知乎 编辑:程序博客网 时间:2024/05/20 12:49

Gradle概述

Gradle作为一种项目构建的工具,与其它的构建工具一样,主要的职责是将输入源转变成目标产物。相比其它构建工具,其最大优势是借助于插件可以灵活地实现功能十分复杂、用途极其广泛的项目构建。

Groovy与Gradle DSL

  1. Groovy作为在java之上设计的脚本语言,相比java,它的代码会更加的简洁优雅(比如方法定义十分简洁,方法的调用可省略圆括号等)这种语言特性使得Groovy特别适合用于设计DSL。

  2. DSL:领域专用语言,简单理解就是一种只能在某种具体领域中使用的语言,比如Html,XML都属于DSL。而Java、Groovy等却是通用的语言,但是它们都可以用来设计DSL。

  3. Gradle DSL:它是以Groovy为基础设计出来的一种DSL,并且这种DSL的形式非常接近于编写配置文件,比如build.gradle。

  4. 小结:当明白Groovy与Gradle的关系之后,很自然地就知道学习Gradle 之前就需要先熟悉Groovy的基础知识。

Gradle工具

  1. 在正式开始Gradle核心之前,建议是先将Gradle的开发环境配置好,并熟悉Gradle的相关工具。

  2. 各个Gradle版本下载地址,本篇基于gradle-3.3-all版本。

  3. 解压gradle-3.3-all,其目录结构如下:
    这里写图片描述

    • bin:这目录下是Gradle的运行脚本,包括类unix与window多种平台;
    • docs:这目录下包括了用户引导、javadoc、Gradle的所有API等相关文档;
    • init.d:默认情况下,该目录只有一个帮助文档,按其说法是可往该目录添加init scripts,被添加的脚本会先在gradle中执行;
    • lib:不多说了,存放了许许多多的jar;
    • samples:这目录下存放了很多gradle开发的样例,降低了学习门槛;
    • src:gradle中的所有源码都在此目录下,弄清楚gradle原理总是离不开源码分析这个话题。
  4. 从Android项目构建的角度,正是此gradle工具的存在才保证了Android项目的构建顺利完成。这也是为什么首次导入某个开源项目时,AS第一步就会下载该项目中gradle-wrapper.properties指定的Gradle工具版本。

Gradle核心

  1. Gradle主要分为三种类型的脚本,虽然这三种脚本在构建过程扮演不同的角色,但都继承自Script接口,并统一使用配置的方式来完成脚本的开发。在下述表格中左边是脚本类型,右边则是这些脚本的代理实现对象:

    Type of script Delegates to instance of Build script Project Init script Gradle Settings script Settings
  2. 从API层面来讲,Build script、Init script和Settings script对于用户而言近乎透明,更多地与用户打交道的是它们对应的代理对象Project、Gradle和Settings,可以认为这三者就是Gradle核心。

  3. Project:一个build.gradle文件对应一个Project实例,注意每次执行Gradle构建时,该项目下的所有build.gradle都会被参与。build.gradle的重点如下:

    • 基础配置块:在build.gradle脚本中已经提供了构建必要的基础配置块,本质上它们就是一个个的方法调用,而参数则是以闭包的方式进行传递,如下图:
      这里写图片描述
    • 变量与作用域:在gradle脚本中使用def关键字定义的变量都是局部变量,更确切的说是该脚本中run方法的局部变量,但可在整个脚本范围内使用;可通过field注解延长其生命周期。
    • Task:Task是Project中相对独立的基本组成单元,Task与Task之前可能存在依赖关系。最简单可理解为一个项目的构建是可拆分为多个步骤,每一个步骤就可以是一个task。task有如下多种定义形式:

      task myTasktask myTask { configure closure }task myTask(type: SomeType)task myTask(type: SomeType) { configure closure }
  4. Gradle:Gradle代理的是gradle初始化脚本,它是先于build脚本运行的。注意:这个脚本是是放置在前面介绍的Gradle工具中的init.d目录下的。在Project对象中,可通过getGradle方法获取该Gradle。目前Gradle提供了如下的API:
    这里写图片描述

  5. Settings:settings.gradle与Settings一一对应,它一般位于项目的根目录,一般用于配置多项目构建中的build.gradle,它也是先于build.gradle执行的。

  6. 三者执行顺序:init -> Settings -> Build

  7. The Build Lifecycle:gradle构建生命周期依次经历如下三个阶段,由gradle命令来触发task的执行

    • Initialization:依据settings.gradle脚本中的include配置,实例化相关的Project实例,且Project与build.gradle一一对应。settings.gradle在Initialization阶段执行
    • Configuration:project完成构建相关的配置,主要是准备好所有与构建相关的task,包括task依赖等
    • Execution:task真正执行的阶段,所有与目标task相关的依赖task会先执行,而这些依赖task如果也存在依赖关系,则被依赖的先执行,否则按task名字的字母顺序执行。

    实例如下:

    settings.gradle

    println 'This is executed during the initialization phase.'

    build.gradle

    println 'This is executed during the configuration phase.'task configured {    println 'This is also executed during the configuration phase.'}task test {    doLast {        println 'This is executed during the execution phase.'    }}task testBoth {    doFirst {      println 'This is executed first during the execution phase.'    }    doLast {      println 'This is executed last during the execution phase.'    }    println 'This is executed during the configuration phase as well.'}
  8. 依赖管理:Gradle对于依赖的管理是非常灵活多变,分为以下几种类型

    • External module dependencies:外部模块依赖,最常见的是远程jar或aar依赖。
    • Client module dependencies:一种特殊的外部模块依赖,特殊在它可以在构建脚本中直接修改该模块的meta-data,比如transitive 。
    • Project dependencies:工程依赖,最常见的是多项目构建中的module工程被依赖。
    • File dependencies:直接引入工程的lib文件,比如项目中lib目录下的jar包、aar包。
    • Gradle API Dependency:声明当前gradle版本的api依赖,辅助开发gradle插件或task。
    • Local Groovy Dependency:声明使用Groovy来开发Gradle插件或task的所需的依赖。

    如下示例:

    dependencies {    // External module dependencies    compile 'com.github.bumptech.glide:okhttp-integration:1.3.1@aar'    compile 'com.github.bumptech.glide:glide:3.6.1'    // Client module dependencies    compile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') {        transitive = true;    }    compile('com.crashlytics.sdk.android:crashlytics-ndk:1.1.2@aar') {        transitive = true;    }    // Project dependencies    compile project(':service')    // File dependencies    compile fileTree(dir: 'libs', include: ['*.jar'])    // Gradle API Dependency    compile gradleApi()       // Local Groovy Dependency    compile localGroovy()}

Gradle命令

  1. Gradle命令是离不开task的,其命令格式为:gradle [options…] [tasks…] 。关于命令的具体参数,可使用gradle –help来查看。

  2. gradle init:新建一个gradle构建脚本项目,包括gradle目录、build.gradle、setting.gradle等。注意:这个task会涵盖gradle wrapper命令。如下实例截图:
    这里写图片描述

  3. gradle wrapper:用于创建gradle wrapper,使得没有安装Gradle的项目也能执行gradle的task。wrapper包括三部分:gradle、gradlew、gradlew.bat,如下截图:
    这里写图片描述

  4. gradle task:打印出项目中的所有task列表,如下图:
    这里写图片描述

  5. gradle properties:打印出属性列表,这些属性都可在build脚步文件中进行修改。如下:
    这里写图片描述

  6. gradle clean:该task是用于移除工程目录下的build目录。

  7. gradle build:该task是用于构建编译整个工程项目,构建的输出都在build目录下。

Gradle调试

  1. Gradle官方提供了一个用于追踪Gradle构建信息的后台,并提供了相应的插件com.gradle.build-scan

  2. 上述链接已有插件的集成,当执行命令:gradle build –scan之后该插件就会自动上传构建信息至后台;

  3. 这个插件后台收集的调试数据还是比较全面的:
    这里写图片描述

  4. 目前对于gradle脚本的开发并没有很好调试手段,这个插件还是有用武之处。

Gradle实践

  1. 新建一个Groovy Library非常简单,新建一个目录,在该目录下执行

    gradle init --type groovy-library

    注意,目前gradle init支持如下的项目类型:

    'basic', 'groovy-application','groovy-library', 'java-application', 'java-library', 'pom', 'scala-library'
  2. 使用linux中的tree命令来打印其目录结构:

    .├── build.gradle├── gradle│   └── wrapper│       ├── gradle-wrapper.jar│       └── gradle-wrapper.properties├── gradlew├── gradlew.bat├── settings.gradle└── src    ├── main    │   └── groovy    │       └── Library.groovy    └── test        └── groovy            └── LibraryTest.groovy
  3. 先关注settings.gradle,它是用于管理大型多项目构建下的gradle脚本的配置,如下配置了总工程的项目名称:

    /* * This settings file was generated by the Gradle 'init' task. * * The settings file is used to specify which projects to include in your build. * In a single project build this file can be empty or even removed. * * Detailed information about configuring a multi-project build in Gradle can be found * in the user guide at https://docs.gradle.org/4.1/userguide/multi_project_builds.html *//*// To declare projects as part of a multi-project build use the 'include' methodinclude 'shared'include 'api'include 'services:webservice'*/rootProject.name = 'NewGradleBuild'
  4. 重点关注build.gradle代码,开头先应用了groovy插件,接着指明了项目依赖的服务器的地址,最后指明了项目的相关依赖,如下代码:

    /* * This build file was generated by the Gradle 'init' task. * * This generated file contains a sample Groovy project to get you started. * For more details take a look at the Groovy Quickstart chapter in the Gradle * user guide available at https://docs.gradle.org/4.1/userguide/tutorial_groovy_projects.html */// Apply the groovy plugin to add support for Groovyapply plugin: 'groovy'// In this section you declare where to find the dependencies of your projectrepositories {    // Use jcenter for resolving your dependencies.    // You can declare any Maven/Ivy/file repository here.    jcenter()}dependencies {    // Use the latest Groovy version for building this library    compile 'org.codehaus.groovy:groovy-all:2.4.11'    // Use the awesome Spock testing and specification framework    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'}
  5. 最后执行gradle build来观察编译之后的工程项目的结构变化,显眼的地方是groovy代码会编译成class并且会被打成jar包:

    .├── build│   ├── classes│   │   └── groovy│   │       ├── main│   │       │   └── Library.class│   │       └── test│   │           └── LibraryTest.class│   ├── libs│   │   └── NewGradleBuild.jar│   ├── reports│   │   └── tests│   │       └── test│   │           ├── classes│   │           │   └── LibraryTest.html│   │           ├── css│   │           │   ├── base-style.css│   │           │   └── style.css│   │           ├── index.html│   │           ├── js│   │           │   └── report.js│   │           └── packages│   │               └── default-package.html│   ├── test-results│   │   └── test│   │       ├── binary│   │       │   ├── output.bin│   │       │   ├── output.bin.idx│   │       │   └── results.bin│   │       └── TEST-LibraryTest.xml│   └── tmp│       ├── compileGroovy│       │   └── groovy-java-stubs│       ├── compileTestGroovy│       │   └── groovy-java-stubs│       ├── jar│       │   └── MANIFEST.MF│       └── test│           └── jar_extract_4777316774274568973_tmp├── build.gradle├── gradle│   └── wrapper│       ├── gradle-wrapper.jar│       └── gradle-wrapper.properties├── gradlew├── gradlew.bat├── log├── settings.gradle└── src    ├── main    │   └── groovy    │       └── Library.groovy    └── test        └── groovy            └── LibraryTest.groovy
原创粉丝点击