美文网首页
Gradle 基础知识

Gradle 基础知识

作者: minhelloworld | 来源:发表于2020-05-14 22:21 被阅读0次

    本文将对Gradle的一些基本概念、用法进行总结,从而避免自己在Android开发过程中的“会而不知所以然”,关于Gradle的高阶用法可以见参考,本文就不再赘述;

    基本概念

    Wrapper

    为了保证gradle版本的一致性,比如我们下载某个Android工程,编译运行前,wrapper会检查你本地是否存在gradle-wrapper.properties文件中声明的gradle版本,如果不存在,就会去下载,通常是个gradlew配合一起使用的,如下示例,可以帮助你更好的理解wrapper的概念;

    [min@TATEMIN-MB0:] gradle $ mkdir wrapper-demo  # 创建一个空的wrapper-demo
    [min@TATEMIN-MB0:] gradle $ cd wrapper-demo/
    [min@TATEMIN-MB0:] wrapper-demo $ gradle -v     # 查看当前gradle的版本
    
    ------------------------------------------------------------
    Gradle 5.4.1
    ------------------------------------------------------------
    
    Build time:   2019-04-26 08:14:42 UTC
    Revision:     261d171646b36a6a28d5a19a69676cd098a4c19d
    
    Kotlin:       1.3.21
    Groovy:       2.5.4
    Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
    JVM:          1.8.0_241 (Oracle Corporation 25.241-b07)
    OS:           Mac OS X 10.15.4 x86_64
    
    [min@TATEMIN-MB0:] wrapper-demo $ gradle wrapper # 创建一个gradle wrapper
    
    BUILD SUCCESSFUL in 0s
    1 actionable task: 1 executed
    [min@TATEMIN-MB0:] wrapper-demo $ tree
    .
    ├── gradle
    │   └── wrapper
    │       ├── gradle-wrapper.jar
    │       └── gradle-wrapper.properties
    ├── gradlew
    └── gradlew.bat
    
    2 directories, 4 files
    # 查看wrapper的内容,可以看到distributionUrl的版本号和我们本地的对齐,此工程如果那运作在一台没有安装过gradle-5.4.1的设备上,会先去下载gradle-5.4.1对应的包,此过程由gradlew+gradle-wrapper.jar完成;
    [min@TATEMIN-MB0:] wrapper-demo $ cat gradle/wrapper/gradle-wrapper.properties
    distributionBase=GRADLE_USER_HOME
    distributionPath=wrapper/dists
    distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
    zipStoreBase=GRADLE_USER_HOME
    zipStorePath=wrapper/dists
    

    GradleUserHome

    在Mac/Linux系统上,此目录即为~/.gradle目录,可以理解为gradle的workspace。

    Daemon

    因为JVM启动速度很慢,大约每次启动在10s左右,所以gradle为了解决这个问题,将gradle设计为如下结构:

    gradle-deamon
    大体的意思即使说,在启动gradle后会同时启动两个进程,一个Client,一个Daemon,Client负责具体的交互,比如命令的接收、日志的打印等等,Daemon负责具体的编译工作并和Client完成交互,Client端推出后,Daemon并不立即退出,如果期间没有新的Client发消息进来,会存活3小时左右,这样就避免了每次gradle启动时等待JVM启动的耗时,另外如果当前启动的Client版本和Daemon不一致,会重新启动一个Deamon

    Daemon 4.0以前,CI相关编译建议加上--no-daemon,因为此时Daemon并不稳定,后续版本无此问题。

    Groovy基础

    动态调用和MOP

    MOP:元对象协议。由 Groovy 语言中的一种协议。该协议的出现为元编程提供了优雅的解决方案。而 MOP 机制的核心就是 MetaClass。
    元编程:编写能够操作程序的程序,也包括操作程序自身,示例如下:

    string = 'hello'
    targetMethod = string.metaClass.getMetaMethod('toUpperCase')
    println(targetMethod.invoke(string))
    

    闭包

    • 闭包是一个开放,匿名的代码块,可以接受参数,返回值并分配给变量

    • 闭包定义:{ [closureParameters -> ] statements },示例:

      //执行一句话  
      { printf 'Hello World' }                                   
          
      //闭包有默认参数it,且不用申明      
      { println it }                   
      
      //闭包有默认参数it,申明了也无所谓                
      { it -> println it }      
          
      // name是自定义的参数名  
      { name -> println name }                 
      
       //多个参数的闭包
      { String x, int y ->                                
          println "hey ${x} the value is ${y}"    
      }
      
    • Android示例:

      def android(closure) = {
          closure()
      }
      
      def ext(closure) = {
          closure()
      }
      
      android {
          ext {
              println("i am ext")
          }
      }
      

    Gradle 构建

    主要理解gradle的核心模型

    • Project

      每个Gradle构建都由一个或多个Project组成。

    • Task

      每个Project由一个或多个Task组成,Task代表构建执行的一些原子工作,比如编译某些类、创建JAR、生成Javadoc等等;

    • Lifecycle与Hook

      Gradle构建的声明周期都分为三个不同的阶段.

      • Initialization

        Gradle支持单项目和多项目构建. 在初始化阶段,Gradle确定将要参与构建的Project,并为每个Project创建一个Project实例(构建文件与Gradle交互的主要API.)

      • Configuration

        在此阶段,将配置项目对象,执行作为构建一部分的所有项目的构建脚本.

      • Execution

        Gradle确定要在配置阶段创建和配置的任务子集. 子集由传递给gradle命令的任务名称参数和当前目录确定. 然后Gradle执行每个选定的任务.

    下面是一个非常好的例子可以理解一下:

    task("hello_world") {
        println("configuration")
    
        doLast {
            println("execution task")
        }
    }
    
    (1..10).each { i ->
        task("task_${i}") {
            int index = i
            if (index % 2 == 0) {
                dependsOn("hello_world")
            }
    
            doLast {
                println("executing task_${index}")
            }
        }
    }
    
    afterEvaluate {
        println("after evaluate")
    }
    

    此脚本最后执行结果如下:

    [min@TATEMIN-MB0:] wrapper-demo $ ./gradlew task_2
    
    > Configure project :  # Configuration阶段
    configuration
    after evaluate
    
    > Task :hello_world    # Execution阶段
    execution task
    
    > Task :task_2               # Execution阶段
    executing task_2
    
    BUILD SUCCESSFUL in 1s
    2 actionable tasks: 2 executed
    

    参考

    相关文章

      网友评论

          本文标题:Gradle 基础知识

          本文链接:https://www.haomeiwen.com/subject/qdrfohtx.html