二十八、安卓工程师必须了解的Gradle知识

概述

Android中使用的编译工具就是 gradle,通常我们使用工程默认生成的 build.gradle就能满足基本需求。但是涉及到复杂的工程结构设计,更优雅的配置写法,这就要求我们对gradle有更深的了解。

首先以下概念是必须要掌握的。

Gradle的构建生命周期

一个安卓项目,从源代码 java 和 资源文件 到最终产物 apk,中间有很多过程,大概可以分为三个大步骤。

  1. 初始化(Initialization):在这一阶段,Gradle 将加载项目的构建配置文件(build.gradle)并创建 Gradle 构建对象。它会解析项目的结构、依赖关系和其他配置,并准备构建过程所需的资源和插件。
  2. 配置(Configuration):在这一阶段,Gradle 将根据初始化阶段中加载的构建配置文件来配置项目的构建。它会执行各个模块的配置任务,解析依赖关系,确定编译选项,处理资源文件,应用插件等。这个阶段主要是确定构建的行为和内容,即告诉 Gradle 应该如何构建项目。
  3. 执行(Execution):在这一阶段,Gradle 将根据配置阶段中确定的构建行为来执行实际的构建任务。它会按照指定的顺序执行各个任务,如编译源代码、处理资源文件、运行单元测试、打包 APK 等。这个阶段是构建过程的实际执行阶段,Gradle 会根据配置和任务之间的依赖关系来自动执行所需的任务。

Task

Task 任务,是gradle工作的基本单元。gradle执行编译动作,都是通过一个个task来进行的.

自定义task

Task之间存在依赖关系

指定依赖关系有很多种方式,下图是其中一种最简单的。

Gradle的构建生命周期中, 配置阶段 会将 所有task的依赖关系确定下来。

Gradle自定义方法

利用def 关键字可以定义一个 方法,写法和java完全类似。并且可以在task中 使用此方法。

利用系统提供的Task构建自己的task

以下就是 创建了我们自己的 copy 任务,并且继承了 系统自带的 Copy任务。

比如我们现有的目录结构是:

执行完任务之后,目录结构如下:

我们自定义copy任务的作用就是,将 src内的所有文件,原样拷贝到 dest目录。

至于这里具体有多少个系统的 type 供我们选择,就需要去gradle的官网阅读文档,而且每一个 gradle版本都会有所不同。

project

一个安卓工程,在 gradle作用下,会生成一个 rootProject对象。 而 工程下的每一个module,都会是一个Project。

比如下图中,我们的整个工程就是一个 RootProject,其余每一个module都是 Project。

我们可以在 rootProject下统筹管理所有的子project,也就是说,我们能做到 在 根目录的build.gradle中,一次性管理所有 module中的依赖配置。

举个很实用的例子:

我们的项目经过长时间的迭代,会引入很多第三方库,而且有的第三方库会有同一个依赖库的版本的冲突,造成编译失败。常用的解决方式是,在出问题的 module 的 build.gradle中强行指定某个 依赖库的版本。

但是这种是属于特例,如果这种特例写的太多,我们自己多个module之间的特例也有可能形成冲突。所以最好的办法,就是在 根目录的 build.gradle 中进行统筹管理这些特例。比如下图:

subprojects{} 实际上是在对所有的子module进行遍历。

project.configurations.all{} 则是对一个module中的所有配置进行遍历

resolutionStrategy.eachDependency{} 又是在对一个配置中的所有依赖进行遍历。

经过了三重遍历,最终得到了每个module的每一个依赖配置。

最终,通过group和name,锁定一个依赖,并通过 details.useVersion() 来指定统一的版本号。

这种写法,比在每一个module中进行分别强制指定依赖版本要好得多。

但是仍有一个缺点,那就是 AndroidStudio无法提供代码提示 ,上图中的${cfgs.androidSupportVersion} 全部都要手动输入或者拷贝。

buildSrc

buildSrc是 编写 gradle插件的其中一种方式,我们在安卓工程中,与app平级,创建一个 buildSrc目录,它是 一个特殊的module,它内部的所有代码,都会转化成gradle插件内容。

buildSrc是解决上面的缺点一个可靠的方式。

在 buildSrc中创建一个 build.gradle.kts文件,并添加 kotlin插件,

当然,为了编译通过,我们还要引入jcenter仓库。

创建 buildSrc/src/main/java目录,并在其中新建 Dependencies.kt,并添加两个类。

Version类中指定所有可能使用到的配置版本。

Deps类中,添加所有依赖,如下图,这是kotlin的语法,其中每一个依赖的字符串都引用到了 上面的Version张的变量。

然后我们就可以 用如下写法去编写依赖 :

最可贵的是,我们在写出Deps.之后,它会默认带出所有的可用的值。

总结

Task是gradle工作的基本单元,每次编译时,都会在 控制台看到很多gradle task正在执行。

每一个project都是由多个task组合而成,每个 module 都包含一个build.gradle,每个build.gradle都会被gradle编译成 project字节码,build.gradle中的所有逻辑,都映射成了project字节码的实现逻辑。

最后buildSrc是我们解决 编写 build内容没有代码提示的 简单有效的办法。

相关推荐
范文杰3 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪3 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪3 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy4 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom5 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom5 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom5 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom5 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom5 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试
LaoZhangAI6 小时前
2025最全GPT-4o图像生成API指南:官方接口配置+15个实用提示词【保姆级教程】
前端