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

前言

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

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插件。

Gradle是什么?

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

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

  • 自动处理包相依关系 - 取自 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 应用的流程和可配置设置。

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详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容