二十八、安卓工程师必须了解的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内容没有代码提示的 简单有效的办法。

相关推荐
QQ1__8115175151 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态1 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子1 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室1 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI1 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing1 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者2 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册2 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李2 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢2 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web