Gradle自动化构建(一)

什么是Gradle

百度说他是基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。

为什么使用Gradle、有什么优势

  • 灵活度高,可以自行修改构建脚本
  • 粒度性,各个部分例如资源等都通过不同的task进行构建
  • 扩展性,可以复用各种插件
  • 兼容性,兼容所有ant、maven

Gradle由什么组成

  • groovy核心语法
  • build script block
  • gradle api

emmm,现在我主要用在Android项目的构建,所以下面就从Android项目的gradle说起


Gradle自动化构建(一)_第1张图片
1ed801d6b5a7b7b4280878c90757bd9.png

local.properties忘记写了,也是一个保存键值对的属性文件,可以引用在gradle中

这里介绍一下上图的各个文件

  • sk_1:第一个'sk_1',就是你创建的项目名,又叫根工程,也是rootProject,他下面可以包含好多module,包括app这个主module,可以统筹所有子project。
  • app、library、multi-image-selector:黄色的三个文件夹app、library、multi-image-selector这三个module其中app是主module,他们三个也叫rootProjcet下的子project,是我们项目中引入的源码库。
  • build.gradle:下面有一个红色的build.gradle 这个就是根工程(rootProject)的构建文件,新创建的项目会在这个文件中添加代码仓(jcenter()、maven()、ivy()等,其中ivy用的很少了),另外就是添加一下gradle所需要的依赖也就是在buildscript下面的dependencies这里添加的(这里和module里面的build.gradle里面的dependencies不同,他主要就是添加gradle所需要的插件.......)
  • gradle.properties:然后是gradle.properties这个文件相当于我们写代码里面的常量类,举个栗子:mCompileSdkVersion = 25然后我在需要制定sdk版本的地方直接给他mCompileSdkVersion.toInteger() 就行了(emmm.避免魔法值了)
  • local.properties:再看local.properties这个文件,也是写一些属性键值对,这个文件是不上git代码仓库的,因为这个文件中保存的就是你本机的配置,和别人的配置并不一样。例如指定一下你的sdk路径。
  • setting.gradle:最后setting.gradle他就是构建时候第一个被执行的文件,里面添加了rootProject所包含的所有子Project(Module)
  • 这里强调一个地方最外层的文件夹叫他rootProject,然后里面的所有module叫他子project,为什么请往下看

为什么说Module在Gradle中叫Project

答:因为Gradle中有两个非常非常重要的概念1.Project 2.Task对应了两个类,他就规定有两种project 一种是根项目也就是rootProject、另一种就是module 也就是rootProject下的子project,而且rootProject和子project是继承关系用起来,我觉得最重要的就是方便rootProject对子project的管理。


先来说下Gradle生命周期吧

  • Initiallzation (Loading初始化阶段,解析整个工程中所有Project,构建所有的Project对应的Project对象)
    就是执行settingGradle 可以在settingGradle中写groovy
  • Configuration (配置阶段,解析所有的projects对象中的task,构建好所有task的拓扑图(有向无环图))
  • Execution(执行阶段,执行具体的task及其依赖的task)
再说下生命周期函数(生命周期回调函数)

常用的有三种方式监听gradle生命周期

  • 监听生命周期第一组方式
    注意这里是中括号,为啥用中括号,因为这是groovy中的闭包的语法
// init 和 configuration 之间的监听 配置阶段开始监听
this.beforeEvaluate {}
//configuration 和 execution 之间的监听 配置完成监听
this.afterEvaluate {}
//执行完成(Execution)后监听
this.gradle.buildFinished {}
  • 监听生命周期的第二组方式
//相当于beforeEvaluate
this.gradle.beforeProject {}
//afterEvaluate
this.gradle.afterProject {}
  • 监听生命周期的第三组方式
/**
 * 第三种监听方式 添加监听器方式 使用gradle api添加监听
 */
this.gradle.addListener()

这里注释很清楚了,就是回调的时机


简单介绍点gradle中常出现的方法、闭包

这里先声明下:你在任何module或者rootProject的build.gradle中写你想执行的代码,就可以看做是在一个叫做project的类中写方法

  • allprojects {}:这个东西一般写在rootProject的build.gradle中,主要作用就是为当前project下所有子project添加公共的内容,举个栗子
allprojects {
    apply from: '../publishToMaven.gradle'
}

这样就同时在所有的子project的build.gradle中添加了上传到maven的依赖,看这个依赖的文件的后缀,其实他也是一个gradle文件,就可以看成是一个执行上传project到maven仓库的工具类,这样你的project(module)才可以上传到maven仓库啊。

  • subprojects {}:看了上面大概可以猜出他是干啥的,就是为所有子project添加公共内容,不包括当前project(怎么看当前是哪个project,看下项目目录层级,你写到那一层的build.gradle里那就是当前project),举个栗子
subprojects { Project project ->
    //publishToMaver.gradle这个依赖实现的就是上传到maven仓库的功能
    if (project.plugins.hasPlugin('com.android.library')) {
        //判断当前工程是否是一个library 如果是就引入上传到maven的功能
        apply from: '../publishToMaver.gradle'//为所有子工程添加上传到Maven的gradle依赖
    }
}
  • ext{}:这个肯定见过,就是扩展当前project(这里说project是一个类)的属性(自定义属性)不懂可以看下标题下面的声明。就是扩展了这个类的字段,不知道说明白了没有,可以把build.gradle当做是一个project类
    看下例子
ext {
    compileSdkVersion = 25
}

就这样我们就可以在所有当前project下的子project中使用这个compileSdkVersion,使用的时候要用this.compileSdkVersion,因为rootProject和子project是继承关系

  • 看下rootProject下的build.gradle
buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }
    }
}

一般都是这样的,这里我们主要解释下buildscript

buildscript { ScriptHandler scriptHandler ->
    //配置我们工程的仓库地址
    scriptHandler.repositories { RepositoryHandler repositories ->
        repositories.jcenter()//添加代码仓库的方法 只要调用就会添加了下面也是这样
        repositories.mavenCentral()
        repositories.mavenLocal()
        repositories.ivy {}
        //私有的maven仓库
        repositories.maven { MavenArtifactRepository mavenArtifactRepository ->
            //公司名字
            name 'personal'
            //一般是内网的仓库url
            url 'http://localhost:8081:/nexus/repositories'
            //配置仓库登录账号密码 自动登录
            credentials {

            }
        }
    }

    //配置我们工程的 *插件* 依赖地址
    //project中也有一个dependencies方法引入的工程使用的第三方库
    //这个时buildScript中的引入**gradle中使用的插件**
    //所以使用gradle构建项目有两个不同的依赖
    scriptHandler.dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'
    }
}

buildscript写完整应该是这样的 ScriptHandler scriptHandler是闭包的参数,buildscript是一个接收闭包为入参的方法这个闭包又有参数叫ScriptHandler scriptHandler

  • 在看下子project的build.gradle中的dependencies
//为应用程序添加第三方库依赖
dependencies {
    //依赖文件夹 使用fileTree
    compile fileTree(includes: ['*jar'], dir: 'libs')
    compile 'jar/aar Name'//依赖远程的jar包/aar
    compile project(':projectName')//依赖源码

    //解决引入第三方库依赖冲突
    compile('jar/aar Name') {
        exclude module: 'support-v4'//module是key 后面是value 解除当前依赖的库中使用的子project
        //第二种解除依赖
        exclude group 'com.android.support'//通过group解除所有com.android.support包下的内容

        //解决传递依赖
        //比如一个第三方依赖B中又依赖了rxjava 我们想通过B依赖rxjava而不再我们自己的gradle中依赖
        //就可以设置 transitive true 这时就依赖了当前第三方依赖B所依赖的rxjava
        //尽量不要传递依赖 因为有可能B在后续升级中就不需要rxjava了 而当前自己工程还依赖rxjava就会报错了
        transitive false
    }

    //引入第三方库的两种方式
    //第三方库类资源都会打入到apk中
    compile 'jar/aar Name'
    //在编译期会吧类资源打入工程中 在运行时不会打入到apk中 如果不进行特殊处理在运行时就会出错
    //依赖的类库只在编译期使用 在运行时并不使用
    //工程是一个库工程 库工程需要引入一个第三方 eg okhttp 主工程也需要使用okhttp 这时候可以使用provided引入okhttp不会
    //与主工程的依赖冲突
    provided('jar/aar Name')

}

写的有点乱,总结下自己对gradle的理解和认识,有些东西不经常用就会忘掉。上面介绍的这些都是针对gradle中的Project这个大模块来讲的,后续还要有task、执行外部命令、还有一些不常用的其他的api,一般也就用这些。emmm...groovy也是要看的,虽然他和java很像,但是还是有一些不同的地方,比如闭包,如果不知道这个东西看gradle就会很恶心哈哈哈。

你可能感兴趣的:(Gradle自动化构建(一))