Gradle原理

来源:互联网 发布:微信备案域名 编辑:程序博客网 时间:2024/05/19 02:30

什么是Gradle

Gradle是一种依赖管理工具,基于Groovy语言,面向Java应用为主,它抛弃了基于XML的各种繁琐配置,取而代之的是一种基于Groovy的领域特定(DSL)语言。Android Studio中新建项目成功后自动下载Gradle。

 

领域驱动设计(DDD

Gradle是一个自动化build工具,所以Gradle面对的领域就是自动化构建这一领域。Gradle是按照DDD的思想设计和开发的,所以自动化构建领域里的大部分概念,在Gradle的源代码里都有一个接口或类与之对应。本文介绍对Gradle新手来说最重要的三个领域对象:ProjectTaskAction

 

Gradle 的编译周期

在解析 Gradle 的编译过程之前我们需要理解在 Gradle 中非常重要的两个对象。ProjectTask

每个项目的编译至少有一个 Project,一个 build.gradle就代表一个project,每个project里面包含了多个task,task 里面又包含很多action,action是一个代码块,里面包含了需要被执行的代码。

在编译过程中, Gradle 会根据 build 相关文件,聚合所有的project和task,执行task 中的 action。因为 build.gradle文件中的task非常多,先执行哪个后执行那个需要一种逻辑来保证。这种逻辑就是依赖逻辑,几乎所有的Task 都需要依赖其他 task 来执行,没有被依赖的task 会首先被执行。所以到最后所有的 Task 会构成一个 有向无环图(DAG Directed Acyclic Graph)的数据结构。

编译过程分为三个阶段:

· 初始化阶段:创建 Project 对象,如果有多个build.gradle,也会创建多个project.

· 配置阶段:在这个阶段,会执行所有的编译脚本,同时还会创建project的所有的task,为后一个阶段做准备。

· 执行阶段:在这个阶段,gradle 会根据传入的参数决定如何执行这些task,真正action的执行代码就在这里.

Project

ProjectGradle最重要的一个领域对象,我们写的build.gradle脚本的全部作用,其实就是配置一个Project实例。在build.gradle脚本里,我们可以隐式的操纵Project实例,比如,apply插件、声明依赖、定义Task等,如下所示:

 


applydependenciestask等实际上是Project的方法,参数是一个代码块。如果需要,也可以显示的操纵Project实例,比如:

1. project.ext.myProp = 'myValue'  

Task

GradleTask等同于AntTarget。在内部,Task被组织成了一个有向无环图(DAGGradle保证Task按照依赖顺序执行,并且每个Task最多只被执行一次。当我们看到下面这段脚本的时候,只要明白两点就可以了:

1. task myTask {  

2.   // ...  

3. }  

1. Project添加一个名为“myTask”的任务

2. 用一个闭包来配置这个任务

在闭包中,我们可以充分利用Gradle提供的DSL来配置任务,比如,给任务添加Action

Action

Task可以包含nActionTask提供了doFirstdoLast方法来给自己添加Action,如下所示 

1. task myTask {  

2.     doFirst {  

3.         println 'hello'  

4.     }  

5.     doLast {  

6.         println 'world'  

7.     }  

8. }  

还提供了<<运算符,如下所示: 

1. task myTask << {  

2.     println 'hello world'  

3. }  

build.gradle脚本的真正作用,就是配置一个Project实例。在执行build脚本之前,Gradle会为我们准备好一个Project实例,执行完脚本之后,Gradle会按照DAG依次执行任务。

 

Gradle是一个框架,它定义一套自己的游戏规则,必须要遵守它设计的规则。
Gradle中,每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。一个具体的编译过程是由一个一个的Task来定义和执行的。

 

 

Gradle的生命周期

1. Initialization -初始化阶段

2. Configuration -配置阶段

3. Execution -执行阶段

 

1.2.1 Initialization - 初始化阶段

初始化阶段会执行项目根目录下的settings.gradle文件,来分析哪些项目参与构建。

所以这个文件里面的内容经常是:

 


这是告诉Gradle这些项目需要编译,所以我们引入一些开源的项目的时候,需要在这里填上对应的项目名称,来告诉Gradle这些项目需要参与构建。

1.2.2 Configuration - 配置阶段

配置阶段会去加载所有参与构建的项目的build.gradle文件,会将每个build.gradle文件实例化为一个Gradleproject对象。然后分析project之间的依赖关系,下载依赖文件,分析project下的task之间的依赖关系。

他会先执行根目录下的build.gradle文件,一般这个文件的内容如下:

 


buildscript中的dependencies是说这个项目依赖com.android.tools.build:gradle:2.2.2来构建。
allprojects 后面是一个闭包,相当于我们执行allprojects这个函数,传入了一个闭包作为参数。其实就是对所有的项目进行迭代,指定所有参与构建的项目使用的仓库。

1.2.3 Execution - 执行阶段

执行阶段来执行具体的task

taskGradle中的最小执行单元,我们所有的构建,编译,打包,debug,test等都是执行了某一个task,一个project可以有多个task,task之间可以互相依赖。例如我有两个task,taskA和taskB,指定taskA依赖taskB,然后执行taskA,这时会先去执行taskB,taskB执行完毕后在执行taskA。

 


 

如图 1 所示,典型 Android 应用模块的构建流程通常依循下列步骤:

1. 编译器将您的源代码转换成 DEXDalvik Executable)文件(其中包括运行在Android设备上的字节码),将所有其他内容转换成已编译资源。

2. APK 打包器将 DEX文件和已编译资源合并成单个APK。不过,必须先签署APK,才能将应用安装并部署到Android设备上。

3. APK 打包器使用调试或发布密钥库签署您的 APK

a. 如果您构建的是调试版本的应用(即专用于测试和分析的应用),打包器会使用调试密钥库签署您的应用。Android Studio自动使用调试密钥库配置新项目。

b. 如果您构建的是打算向外发布的发布版本应用,打包器会使用发布密钥库签署您的应用。

4. 在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,减少其在设备上运行时的内存占用。

构建流程结束时,您将获得可用来进行部署、测试的调试 APK,或者可用来发布给外部用户的发布APK

0 0