1. Gradle是个构建工具,不是语言
  2. 它用了Groovy语言创造了一种DSL、但它本身不是语言

题外话:理解Groovy语言的闭包

  1. Java不支持方法的参数传递一个方法(或者叫函数),只能传递一个匿名对象做到类似的功能
  2. Kotlin是支持函数的参数传递一个函数的
  3. Groovy也支持,但是不叫Lambda,叫做闭包。而且比Kotlin的Lambda表达式更强,传递一个Closure
  4. 所以android studio的gradle文件下的buildscript {} android {} dependencies {}等其实都是一些方法
    image.png

问题

  • 为什么Groovy可以写出类似JSON格式的配置?

因为它们其实都是方法调用,只是用闭包来写成了看起来像是JSON的格式。

  • Gradle如何构建?
    按照 gradle 的规则(build.gradle、settings.gradle、gradle-wrapper、gradle 语法)

1. Gradle配置文件拆解

buildTypes 和 productFlavors

关于buildTypes

新建项目时gradle文件会默认配上:
image.png
在Build Variants里查看会有debug、release两个版本:
image.png
在buildTypes可自定义增加一个类型用于区分不同版本:
image.png
此功能可用于很多用途,比如:项目需要一个正式版(release)、测试版(debug)、内部版本(internal,随意命名)。这时候buildTypes功能简直是雪中送炭了。
image.png

再次假设,要求每个版本的界面有些细微的不同点,比如:界面的右上角有个小点,release不显示,debug显示绿色,internal显示黄色
image.png
如图所示;在src下新建release、debug、internal三个文件夹。会自动根据环境来调用对应文件夹下的方法。
然后新建一个BuildTypes类,在main文件下的MainActivity调用一个drawBadge()方法
image.png
而这个drawBadge()方法则是会根据环境去release、debug、internal三个文件下的BuildTypes类里寻找
image.png
drawBadge()方法实现如下:

  • release下空实现:

image.png

  • debug下实现:
    image.png
  • internal下实现
    image.png

这样便可实现了在不同环境下显示有差别的需求了。

关于productFlavors

用于「多渠道」打包,假设发布APK分为国内版和海外版、是否付费,或者根据应用市场来区分为:华为版、小米版、魅族版等等渠道,就要用到productFlavors功能了
image.png
image.png
以上用:是否付费和是否国内/海外两个维度来区分版本。

task

  • 使用方法: ./gradlew taskName
  • task 的结构:

    1. task taskName {
    2. 初始化代码
    3. doFirst {
    4. task 代码
    5. } doLast {
    6. task 代码
    7. }
    8. }
  • doFirst() doLast() 和普通代码段的区别

    • 普通代码段:在task创建过程中就会被执行,发生在configuration阶段

    • doFirst()和doLast():在task执行过程中被执行,发生在execution阶段。如果用户没有直接或间接执行 task,那么它的doLast()doFirst()代码不会被执行

    • doFirst()和doLast()都是task代码,其中doFirst()是往队列的前面插入代码,doLast()是往队列的后面插入代码

  • task的依赖:可以使用task taskA(dependsOn: b)的形式来指定依赖。指定依赖后,task会在自己执行前先执行自己依赖的task。

compile, implementation 和 api

implementation:不会传递依赖
compile / api:会传递依赖;api是compile 的替代品,效果完全等同当依赖被传递时,二级依赖的改动会导致 0 级项目重新编译;当依赖不传递时,二级依赖的改动不会导致 0 级项目重新编译

2. Gradle项目结构

Gradle Wrapper

指的是项目目录下的gradlew文件(切换到Project目录)。Wrapper用来包装gradle的东西,通过Wrapper找到gradle,查找本地如果有gradle则使用,没有则去下载。这么做的好处是减少项目大小,使用指定版本的gradle

gradle-wrapper.properties则是gradle的一些配置

  • 通过「只同步版本,不同步文件」的方式来减小协作项目的大小
  • 每个人电脑上的 Gradle 存放在固定位置,然后使用 Gradle Wrapper 的配置来取用对应的版本就行了

settings.gradle

项目的结构配置,谁是主程序,谁是model的配置
image.png
当然也可以用AS的窗口功能Project Structure进行配置

3. Gradle执行的生命周期

三个阶段

  1. 初始化阶段:执行 settings.gradle,确定主 project 和子 project
  2. 定义阶段:执行每个 project 的 bulid.gradle,确定出所有 task 所组成的有向无环图
  3. 执行阶段:按照上一阶段所确定出的有向无环图来执行指定的task

在阶段之间插入代码

  • 一二阶段之间:
    settings.gradle的最后
    image.png
  • 二三阶段之间:
    在build.gradle里: ```groovy // 调用afterEvaluate方法 afterEvaluate {

} ```