半小时掌握Android Gradle

御弟哥哥 等级 933 0 1
标签: gradle闭包Java

目前国内对Android领域的探索已经越来越深,不少技术领域如插件化、热修复、构建系统等都对Gradle有迫切的需求,不懂Gradle将无法完成上述事情。所以Gradle必须要学习。

Gradle 里的几乎任何东西都是基于这两个基础概念:

  • task
  • project

掌握了这两个,你就掌握了一大半的 Gradle 知识了。

首先讲 Task

字面理解为任务,Gradle 中所有执行的事件都是借由 Task 执行的。
例如我们新建一个 Android 工程,在其根目录中输入:

gradle tasks -q 

可以看到如下输出(你可能需要事先配置gradle的环境变量,或也可使用./gradlew替代):

半小时掌握Android Gradle

根据上图可以看到当前工程中的每条task都已罗列出,并且有黄色的输出表示当前task的描述。
其中-q表示忽略gradle本身的log信息,加上这个参数可以屏蔽很多无关的输出,不加也不会影响执行。

Task声明格式

声明一个 task 只需要在任务名前面加上task就可以了,例如下面声明了一个hello的Task。

task hello 

通常我们会给task附带一些执行动作,称之为Action,例如

hello.doFirst{
    println "hello first"
}

hello.doLast{
    println "hello last"
} 

也可以附带一个闭包配置,称之为Configuration,闭包中不仅可用做赋值操作,也可以执行一些自动执行的配置。

hello {
    println "hello"
} 

Task依赖

单独声明一个task在实际开发中几乎不会有任何的意义,更多的时候是让多个task组合起来,一个依赖另一个,形成一连串的任务集。

task hello

hello.doFirst{
    println "hello "
}

task world(dependsOn: "hello") << {
    println "world"
} 

上面这段代码定义了两个task,当我们执行hello任务的时候,会输出 hello,而执行world任务的时候,由于声明了dependsOn: "hello",表示world依赖hello,会先执行hello,再执行world。

task xxx << {
} 

这样的语法等价于

task xxx
xxx.dolast {
} 

你可以在任意位置新建一个名为build.gradle的文本,来练习上面讲述的task定义与依赖。

半小时掌握Android Gradle

gradle, android, kotlin, tasks

接着讲 Project

Android
   │ 
   ├──app
   │   └──build.gradle
   │
   ├──library
   │   └──build.gradle
   │
   ├──*.properties
   │
   ├──build.gradle
   │
   └──setting.gradle 

一个 Android 工程,通常是由上述结构构成,其中有着许多不为人知的巧妙用法。

setting.gradle文件

关于setting.gradle中也可以写代码,是很多人不知道的。在setting.gradle文件中,可以指定一个project位置,这里就可以将一个外部工程中的模块导入到APP工程中了。

getLocalProperties().entrySet().each { entry ->
    def moduleName = entry.key
    if (Boolean.valueOf(entry.value)) {
        def file = new File(rootProject.projectDir.parent, "/${moduleName.replace("\\W", "")}/${moduleName.toLowerCase()}")
        if (file.exists()) {
            include ":${moduleName.toLowerCase()}"
            project(":${moduleName.toLowerCase()}").projectDir = file
        }
    }
} 

build.gradle

一个项目的根gradle文件,用于描述这个项目的统一资源,其中包括各子资源的使用方式、插件的依赖环境等等。

subprojects{
    apply plugin: 'com.android.library'
    dependencies {
      compile 'com.xxx.xxx:xxx:1.0.0'
   }
} 

通常我们在每个模块都会引用的 aar 的时候,都会在每个模块里面都去手动的compile一遍,例如support包。 但实际上有一个非常简单的办法,写一遍就可以了,就是在项目的根gradle文件中的subprojects闭包中声明这个dependencies

通常在写compile依赖的时候,我们都会写成这样:

compile 'com.android.support:appcompat-v7:25.0.0' 

其实在gradle中,这是一个方法调用,它的本质是compile()方法传入了一个map参数,因此完整的写法实际上是这样的:

compile group: 'com.android.support' name:'appcompat-v7' version:'25.0.0' 

同时,map 的可使用 key 不只是有常用的groupnameversion,还包括不常用的configurationclassifier等等。

再看Task

Groovy 是基于 Java 的,只不过在这基础上加了一大堆的闭包,来帮助更方便的开发构建脚本。如果你不会 Groovy,没关系,当成 Java 写就行了,其实当成 Kotlin 写是最恰当的。如果你还不会 Kotlin,我强烈推荐你查看我的 【 Kotlin Primer 】系列文章

每个Task都可以配置其输入与输出,如果一个Task的输出与上一次的输出一致,则不会重复执行。此刻,会在命令行中输出UP-TO-DATE表示已经是最新的结果。
例如如下Task:

task transform {
    ext.srcFile = file('hello.txt')
    ext.destDir = new File(buildDir, 'generated')
    inputs.file srcFile
    outputs.dir destDir
    doLast {
        destDir.mkdirs()
        def ins = new BufferedReader(new FileReader(srcFile))
        def stringBuilder = new StringBuilder()
        def temp
        while ((temp = ins.readLine()) != null) {
            stringBuilder.append(temp)
        }
        def destFile = new File(destDir, "world.txt")
        destFile.text = stringBuilder.toString()
    }
} 

重复执行后会输出UP-TO-DATE

半小时掌握Android Gradle

gradle, android, kotlin, tasks

骚操作的背后

学习任何一门技术,最快的途径就是看源码,gradle的源码位于src目录中,例如在我本机的路径为:
/Users/zhanghongjun/.gradle/wrapper/dists/gradle-3.3-all/55gk2rcmfc6p2dg9u9ohc3hw9/gradle-3.3/src
本地新建一个普通Java工程,导入源码查看代码与注释,这是最好的学习资料。

task hello 

在 Groovy 中,方法括号可以省略,如果字符串的类型是可以被推断的,那么引号也可以省略

public interface org.gradle.api.Project{
    Task task(String name);
    Task task(String name, Closure configureClosure);
}

// TaskFactory
public TaskInternal createTask(Map<String, ?> args) {
} 

闭包的存在,目的是为了更好的为对象初始化。同 Kotlin 一样,当闭包做为最后一个参数的时候,可以省略括号。

Copy a = task(myCopy, type: Copy)
a.from 'resources'
a.into 'target'
a.include('**/*.txt', '**/*.xml', '**/*.properties') 

等价于

task myCopy(type: Copy)

myCopy {
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
} 

本章就讲到这里,下一篇讲如何创建一个Gradle插件,完成编译时向指定类或新生成类中动态添加代码(包括jar包中)。

收藏
评论区

相关推荐

Gradle技术之四 - Gradle的Task详解
1 Gradle的Task详解 1 Task定义和配置 2 Task的执行 3 Task的依赖和执行顺序 4 Task类型 5 Task结合gradle的生命周期 6 Task实战 1.1 Task定义和配置 1.1.1 查看所有的task java ./gradlew tasks 输出 Task :tasks
半小时掌握Android Gradle
目前国内对Android领域的探索已经越来越深,不少技术领域如插件化、热修复、构建系统等都对Gradle有迫切的需求,不懂Gradle将无法完成上述事情。所以Gradle必须要学习。 Gradle 里的几乎任何东西都是基于这两个基础概念: task project 掌握了这两个,你就掌握了一大半的 Gradle 知识了。 首先讲 Task
unity android V1签名
unity 2018版本默认签名会进行V1 V2签名。如果只想进行V1签名的话可以进行以下操作。 1.调整为gradle打包 2.publishing settings里面选择custom gradle template, 3.在gradle配置里面 加入下述代码   ![](https://oscimg.oschina.net/oscnet/up-
Android Studio 3.0 下 Cordova 打包时 Gradle 兼容性问题解决
升级到 Android Studio 3.0, Gradle 升级为 4.3.1 版本,使用 cordova build android 出错. 解决方案: windows 系统以下命令行在 MINGW 的bash 窗口中执行 1. 下载文件 `https://downloads.gradle.org/distributions/gradle-4.3.1
Android Studio 编译异常Could not execute build using Gradle installation解决办法
**Android Studio 编译异常Could not execute build using Gradle installation解决办法** 参考文章: [(1)Android Studio 编译异常Could not execute build using Gradle installation解决办法](https://www.oschi
Android Studio3.1.0升级问题记录
每次升级Android Studio时,一般情况下Gradle版本的也会相应的升级,我之前Android Studio 3.0.1、Gradle 是4.1升级后为:Android Studio 3.1.0、Gradle 为4.4。 升级完成后先是报一堆错(每次都升级都是-。-) 第一个错如下: ------- The SourceSet 'in
Android Studio中的Gradle是什么?
### 问题: _Gradle is a bit confusing to me, and also for any new android developer._ **Gradle让我有些困惑,对于任何新的android开发人员也是如此。** _Can anyone explain what Gradle in Android Studio is and
Android Studio里Gradle Sync同步慢问题的解决方法
Android studio更新到3.3.1,完成后,gradle sysnc一直同步,1个小时后还在转圈圈。同步慢的不能忍受。 如何解决,网上一搜,发现阿里云有镜像,只需要添加相应的url地址就可以下载。如图,在gradle scripts–>build gradle。打开该文件。 ![](https://oscimg.oschina.net/oscn
AndroidStudio Gradle手动下载和安装
操作流程概述: ======= 下载好的压缩包和解压后的文件夹复制到gradle-5.5.1-all --->97z1ksx6lirer3kbvdnh7jtjg文件夹下,将gradle-5.5.1-all.zip.part文件删除,复制一份gradle-5.5.1-all.zip.lck文件,重命名为gradle-5.5.1-all.zip.ok,重启An
Gradle 构建 android 应用常见问题解决指南
前言 -- android gradle 插件已经发展到0.5.7,同时gradle 本身也到了1.8,相比两个月前,android gradle 更快,更完善,也更好用了,为了让各位androider 早日用上gradle这样的神器,特地写一篇关于gradle一些奇葩错误的解决指南. ### 使用最新的gradle android插件 以前我们写的时
Gradle使用杂记
1、配置环境变量 GRADLE\_HOME 2、把gradle缓存目录指向了gradle安装目录下的.gradle目录,设置环境变量GRADLE\_USER\_HOME GRADLE\_USER\_HOME %GRADLE\_HOME%\\.gradle 或者指定目录 GRADLE\_USER\_HOME D:\\gradle\\.grad
Gradle的Android插件
Android构建系统由一个_Gradle_的Android插件组成。 [Gradle](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fwww.gradle.org%2F)是一个高级的构建工具集,它可以管理依赖,并使你能够定义定制化的构建逻辑。Android Studio使用了一个Gradl
Gradle的基本使用
### Gradle的介绍 > Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。 > > 面向Java应用为主。当前其支持的语言限于Java、Groovy和Scala,计划未来将支持更多的语言。 ### Gra
SpringBoot25 gradle安装、利用gradle创建SrpingBoot项目
1 gradle安装 ----------   技巧01:gradle依赖JDK或者JRE,而且版本至少时1.7 ![](https://oscimg.oschina.net/oscnet/0323e19757d8af82723fd31dedc3d167562.png) ###   1.1 下载安装包     到[gradle官网](https://
SpringBoot25 gradle安装、利用gradle创建SrpingBoot项目
1 gradle安装 ----------   技巧01:gradle依赖JDK或者JRE,而且版本至少时1.7 ![](https://oscimg.oschina.net/oscnet/0323e19757d8af82723fd31dedc3d167562.png) ###   1.1 下载安装包     到[gradle官网](https://