摘要:工作包含三个阶段首先是初始化阶段。阶段完了后,整个的以及内部的关系就确定了。对象显然,每一个都会转换成一个对象。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
前言
做为一个做Android的同学,我想对于“Gradle”是再熟悉不过了,但是对于Gradle却是有点陌生,几个月前,只是停留在这样简单的使用上。
compile “com.strange.unfamiliar:1.0”
什么让我意识到其重要性呢?秋招完后,刷刷拉勾,看到杭州某创业公司对应届Andoid 40k的诱惑,赶紧投了一波,投投投,然后收到了面试邀请,刚开始面,感觉这不按套路出牌啊,并不是很偏cs基础,而是在工程实践上,期间问到了gradle的问题,当时内心OS
勉强凑合了几句之后,继续追问,然后全程
面完之后要了面试官的联系方式,进行了一些沟通,意识到了其重要性,然后想着通过项目驱动来深入的学习一波,决定撸QQ空间热修复实现方式中打补丁包的Gradle插件,没错,就是要抄个nvwa。
so,准备出一系列文章来分享整个学习的过程。本篇将对Gradle的一些功能,重要性和其一些基础做下讲解,接下来,将进行Android项目中Gradle的讲解,如何在AndroidStudio中使用Gradle来进行一些自定义构建。接着来进行一个简单的插件实现,最后着手来进行hotfix插件的实现,共分为四个部分,希望在对自己的学习做一个总结的同时,能够让零基础入门的Gradle的能够跟随博客对Gradle有个认识,同时能够实现一个简单的Gradle插件。
Gradle是什么?Gradle是一个基于Apache Ant和Apache 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 构建项目,构建的输出都相同。
如上图所示,在一个Project中,除了我们项目自身的代码和资源之外,会有多个与项目构建相关的.gradle文件,这些.Gradle文件用来对于我们使用Gradle进行构建项目的整个过程中来使用。
Gradle中,每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。
####Gradle工作流程
Gradle的工作流程如下图所示,在每一个工作流程的前后,我们都可以进行一些hook操作,来满足自己的需求。
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 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中支持动态类型,即定义变量的时候可以不指定其类型。(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详解
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/13554.html
摘要:例如,调试构建类型支持调试选项,使用调试密钥签署而发布构建类型则可压缩混淆以及使用发布密钥签署进行分发。产品风味是可选项,并且您必须手动创建。指定需要将其与应用的一起打包的仅运行时依赖项。如果运行时无需此依赖项,这将有助于缩减的大小。 前言 前一篇文章,对Gradle进行了一个概述,同时对于Groovy语言进行了简单的介绍,有了之前的基础,现在就可以进行更细致化的学习,来学习一下在An...
摘要:微信这类怎么做谈谈八款开发者必备的小工具八款开发者必备的小工具笔记之图像压缩开发中的图像压缩是一个很重要的部分。 Android 攻城狮—全套必备神级工具(开发,插件,效率) 如果你有用的酸爽的软件,请下面留言。我会持续更新。。。 替你 总结的 Gradle 配置 关于 Gradle 配置的一些总结,欢迎交流! 常用的代码片段,不断更新 项目中平常会用到的代码片段,以及一些收集的好的代...
摘要:对下半年所分享的文章进行整理,上半年总结的篇好文请点击这里,很多读者当时忘记了收藏,以致于查找一篇历史文章很费劲,因此在这里顺便做下记录。目前就分下下面几个大类,没有更多细分,已基本可以查找了。 对下半年所分享的文章进行整理,上半年总结的 98 篇好文请点击这里,很多读者当时忘记了收藏,以致于查找一篇历史文章很费劲,因此在这里顺便做下记录。目前就分下下面几个大类,没有更多细分,已基本可...
摘要:的权限问题确实给开发者带来了开发难度,那么如何降低难度呢,在此向大家介绍框架,如果你使用过,那么使用将会很简单,也很容易理解其原理,具体如何使用在此不介绍。你要做的事委托给生成的类详细的说明,以及使用指南和代码检视,可在之后的博文中讲解。 这是一个系列,我们将其命名为android最佳实践,如果你还没有看之前的文章: Android最佳实践(一) android最佳实践(二) andr...
摘要:这是一个系列,我们将其命名为最佳实践,如果你还没有看之前的文章最佳实践二最佳实践三最佳实践四最佳实践五最佳实践六之扫描二维码模块最佳实践感谢给的灵感,希望这次专题能认真的走下去,其他翻译会同步进行。 这是一个系列,我们将其命名为android最佳实践,如果你还没有看之前的文章: Android最佳实践(二) android最佳实践(三) android最佳实践(四) android最佳...
阅读 4073·2021-10-13 09:39
阅读 1686·2019-08-29 11:12
阅读 989·2019-08-28 18:16
阅读 2144·2019-08-27 14:27
阅读 1710·2019-08-26 12:16
阅读 1086·2019-08-26 12:13
阅读 2845·2019-08-26 10:59
阅读 2001·2019-08-23 18:27