关于Android Gradle你须要知道这些(1)

前言

作为一个作Android的同窗,我想对于“Gradle”是再熟悉不过了,可是对于Gradle倒是有点陌生,几个月前,只是停留在这样简单的使用上。android

compile “com.strange.unfamiliar:1.0”
复制代码

什么让我意识到其重要性呢?应该是在秋招完后,刷刷拉勾,看到杭州某创业公司对应届Andoid 40k的诱惑,赶忙投了一波,投投投,而后收到了面试邀请,刚开始面,感受这不按套路出牌啊,并非很偏cs基础,而是在工程实践上,期间问到了gradle的问题,当时心里OS程序员

勉强凑合了几句以后,继续追问,而后全程面试

面完以后要了面试官的联系方式,进行了一些沟通,意识到了其重要性,而后想着经过项目驱动来深刻的学习一波,决定撸QQ空间热修复实现方式中打补丁包的Gradle插件,没错,就是要抄个nvwa。编程

so,准备出一系列文章来分享整个学习的过程。文章实际上是从去年已经开始写了两篇,而后持续delay了,这里从新捡起来。本篇将对Gradle的一些功能,重要性和其一些基础作下讲解,接下来,将进行Android项目中Gradle的讲解,如何在AndroidStudio中使用Gradle来进行一些自定义构建。接着来进行一个简单的插件实现,最后着手来进行hotfix插件的实现,共分为四个部分,但愿在对本身的学习作一个总结的同时,可以让零基础入门的Gradle的可以跟随博客对Gradle有个认识,同时可以实现一个简单的Gradle插件。bash

Gradle是什么?

Gradle是一个基于Apache AntApache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML。服务器

那么Gradle相比于Ant 和 Maven的构建方式,有那些优点呢?markdown

  • 自动处理包相依关系 - 取自 Maven Repos 的概念
  • 自动处理布署问题 - 取自 Ant 的概念
  • 条件判断写法直觉 - 使用 Groovy 语言

过去 Java 开发者经常使用 Maven 和 Ant 等工具进行封装布署的自动化,或是二者兼用,不过这两个包彼此有优缺点,若是频繁改变相依包版本,使用 Ant 至关麻烦,若是琐碎工做不少,Maven 功能不足,并且二者都使用 XML 描述,至关不利于设计 if、switch 等判段式,即便写了可读性也不佳,而 Gradle 改良了过去 Maven、Ant 带给开发者的问题,至今也成为 Android Studio 内置的封装布署工具。闭包

Android中Gradle能够作什么?

上一篇文章中讲到了一个Android项目的构建过程,Android 构建系统编译应用资源和源代码,而后将它们打包成可供您测试、部署、签署和分发的 APK。Android Studio 使用 Gradle 这一高级构建工具包来自动化执行和管理构建流程,同时也容许您定义灵活的自定义构建配置。每一个构建配置都可自行定义一组代码和资源,同时对全部应用版本共有的部分加以重复利用。Android Plugin for Gradle 与这个构建工具包协做,共同提供专用于构建和测试 Android 应用的流程和可配置设置。app

Gradle 和 Android 插件独立于 Android Studio 运行。这意味着,能够在 Android Studio 内、使用计算机上的命令行工具或在未安装 Android Studio 的计算机(例如持续性集成服务器)上构建 Android 应用。若是您不使用 Android Studio,能够学习如何从命令行构建和运行您的应用。不管您是从命令行、在远程计算机上仍是使用 Android Studio 构建项目,构建的输出都相同。函数式编程

Android项目结构图

如上图所示,在一个Project中,除了咱们项目自身的代码和资源以外,会有多个与项目构建相关的.gradle文件,这些.Gradle文件用来对于咱们使用Gradle进行构建项目的整个过程当中来使用。

Gradle中,每个待编译的工程都叫一个Project。每个Project在构建的时候都包含一系列的Task。好比一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。

####Gradle工做流程

Gradle的工做流程以下图所示,在每个工做流程的先后,咱们均可以进行一些hook操做,来知足本身的需求。

Gradle工做流程

Gradle工做包含三个阶段:

  • 首先是初始化阶段。对咱们前面的multi-project build而言,就是执行settings.gradle
  • Initiliazation phase的下一个阶段是Configration阶段。
  • Configration阶段的目标是解析每一个project中的build.gradle。好比multi-project build例子中,解析每一个子目录中的build.gradle。在这两个阶段之间,咱们能够加一些定制化的Hook。这固然是经过API来添加的。
  • Configuration阶段完了后,整个build的project以及内部的Task关系就肯定了。一个Project包含不少Task,每一个Task之间有依赖关系。Configuration会创建一个有向图来描述Task之间的依赖关系。因此,咱们能够添加一个HOOK,即当Task关系图创建好后,执行一些操做。
  • 最后一个阶段就是执行任务了。固然,任务执行完后,咱们还能够加Hook。

简言之,Gradle有一个初始化流程,这个时候settings.gradle会执行。 在配置阶段,每一个Project都会被解析,其内部的任务也会被添加到一个有向图里,用于解决执行过程当中的依赖关系。而后才是执行阶段。你在gradle xxx中指定什么任务,gradle就会将这个xxx任务链上的全部任务所有按依赖顺序执行一遍!

Gradle主要有三种对象

这三种对象和三种不一样的脚本文件对应,在gradle执行的时候,会将脚本转换成对应的对象:

  • Gradle对象:当咱们执行gradle xxx或者什么的时候,gradle会从默认的配置脚本中构造出一个Gradle对象。在整个执行过程当中,只有这么一个对象。Gradle对象的数据类型就是Gradle。咱们通常不多去定制这个默认的配置脚本。
  • Project对象:每个build.gradle会转换成一个Project对象。
  • Settings对象:显然,每个settings.gradle都会转换成一个Settings对象。

构建的生命周期,首先根据settings.gradle文件构建出一个Seetings对象,而后根据Seetings中的配置,建立Project对象,去找各个project下的build.gradle文件,根据文件内容来对project对象进行配置。

一个project中Task的数量,取决于其中应用的插架的数目多少,经过

apply plugin: 'com.android.library' 

复制代码

一个Task包含若干Action。因此,Task有doFirst和doLast两个函数,用于添加须要最早执行的Action和须要和须要最后执行的Action。Action就是一个闭包。对于原有的Task,咱们能够在其执行以前或者执行以后,进行一系列的Hook操做,在其执行以前和执行以后,添加一些操做。

tasks.getByName("task"){  
   it.doLast{  
       println "do the task"
     }  
}  
复制代码

Groovy概述

这里将对Groovy语言进行一个简单的介绍,经过简单地语法上的介绍,能够很好地看明白接下来对于构建过程当中一些简单地Groovy语法。经过简短的介绍,能够很好地帮助咱们看懂Gradle中的一些配置信息。

Groovy是一种动态语言,基于Java并拓展了Java。 Java程序员能够无缝切换到使用Groovy开发程序。Groovy让写Java程序变得像写脚本同样简单。写完就能够执行,Groovy内部会将其编译成Java class而后启动虚拟机来执行。下图是Groovy和Java代码和JVM的关系图。

Groovy和Java,JVM关系

语言概述

  • Groovy中支持动态类型,即定义变量的时候能够不指定其类型。(def不是必须的,可是为了代码清晰,建议仍是使用def关键字)
def a = 5;
def b = "groovy"

复制代码
  • 函数的定义,咱们也无需进行参数类型的声明,同时也能够不进行返回值类型的声明,可是须要经过def字段来定义,函数的最后一行做为返回值。
def function1(arg1, arg2) {
	arg1 + arg2
}

String function2(str1, str2) {
	return str1 + str2
}

复制代码
  • 函数调用支持 参数名:参数值方式调用
apply plugin: 'com.android.library'

复制代码

plugin:参数名,'com.android.library':参数值

  • 强大字符串支持功能
//单引号对应Java中字符串
str1 = 'this string'

//双引号,可经过$进行相应的转译
x = 1
str2 = "This is $x"

//经过换行实现每一行的间距
str3 = '''begin line1 line2 end'''

复制代码
  • 闭包

(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即便已经离开了创造它的环境也不例外。因此,有另外一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。对于闭包的实现,从函数式编程的角度来看就为了解决一个输入对应一个输出的问题。例如当咱们想实现一个加法,咱们必须经过传递两个参数来实现,可是借助于函数式编程,咱们能够作到只传递一个参数。

function plusAny(first) {
   return function(second) {
        return first + second;
   }
}

var longLiveSeniorFunc = plusAny(1);

longLiveSeniorFunc(1); 

复制代码
  • Closure结构定义
def xxx = {paramters -> code}  
def xxx = {无参数,纯code} 

复制代码

根据上述两种结构,下面分别举例

def closure = {
	String param ->
	println "This is $param"
}

复制代码
def closure = {
	println 'This is closure'
}
复制代码
  • 如何调用闭包
closure.call('Hello')
closure('Hello')
复制代码

闭包隐含一个自身参数it

def closure = {
	println "This is $it"
}

复制代码

当闭包做为一个函数的参数时

def testClosure(Closure closure) {
	closure()
}

testClosure(
	println 'Test'
)

复制代码

总结

本文围绕Gradle是什么,能够作什么,在Android中起到了什么做用,而后是Gradle的工做流程,Gradle中使用语言Groovy的一个概述,帮助咱们了解如何更好的使用Gradle。

参考文章

深刻理解Android(一):Gradle详解

相关文章
相关标签/搜索