urlname
type
Post
password
SyncToConfluence
category
Android
date
Mar 8, 2025
slug
81c0c866-215d-4807-9e6f-ba9647172d0e
icon
Button
catalog
summary
tags
Android
Gradle
学习笔记
cover
Status
BusyTime
Status 1
status
Published
引言
在上一篇文章 “Gradle系列——Transform入门之基础概念:定义、作用与核心价值” 中,我们已经初步了解了 Gradle Transform 的基本概念、核心价值以及与 Task 的区别。为了更深入地掌握 Transform 技术,本文将聚焦于 Transform 的 核心组件 和 概念模型。理解这些核心要素,是编写自定义 Transform,并将其有效地应用于 Android 构建流程的关键。
本文将详细剖析
TransformInvocation、TransformInput、TransformOutput 以及TransformAction 这四大核心组件,并阐述它们之间的相互关系,构建起 Gradle Transform 的完整概念模型。Transform 的核心组件
Gradle Transform 的强大功能,是由其精巧的核心组件协同运作实现的。理解这些组件的作用和相互关系,有助于我们更好地掌握 Transform 的工作原理,并能更有效地进行自定义扩展。
TransformInvocation 接口:Transform 执行的上下文
TransformInvocation 接口是 Transform 执行过程中的 核心上下文 (Context) 载体。当 Gradle 调度执行一个 Transform 时,它会创建一个 TransformInvocation 实例,并将其传递给 Transform 的 transform() 方法。TransformInvocation 提供了 Transform 执行过程中所需的一切信息,包括:- 构建输入 (Inputs):通过
getInputs()方法获取,包含了 Transform 的所有输入信息,可以是TransformInput对象的集合。
- 构建输出 (Outputs):通过
getOutputs()方法获取,用于指定 Transform 的输出路径,生成TransformOutput对象。
- 上下文信息 (Context):通过
getContext()方法获取,提供了构建过程中的全局上下文信息,例如: isIncremental():指示当前构建是否为增量构建。getTemporaryDir():提供用于存放临时文件的目录。getVariantName():获取当前构建变体 (Variant) 的名称,例如 "debug" 或 "release"。getProjectPath()/getRootProjectPath():获取项目路径和根项目路径。- 以及其他与构建环境和配置相关的信息。
TransformInvocation 的关键作用在于为 Transform 的执行提供了一个统一的、结构化的环境,使得 Transform 可以在隔离的环境中安全地进行构建产物的转换操作,并能获取必要的构建信息。代码示例:
- 上述代码片段中主要展示了在
TransformAction的transform()方法中,如何通过TransformInvocation对象获取构建上下文信息。
transformInvocation.getContext().isIncremental():获取是否为增量构建的标志。
transformInvocation.getContext().getVariantName():获取当前构建变体的名称。
transformInvocation.getContext().getTemporaryDir():获取临时目录的 File 对象。
TransformInput 接口:构建的输入源
TransformInput 接口代表了 Transform 的 输入源,它定义了 Transform 可以接收的构建产物的形式。 TransformInput 主要有两种具体的实现类型:- DirectoryInput (目录输入): 表示一个目录形式的输入源。通常用于处理 未打包 的构建产物,例如:
- Java/Kotlin 源代码编译后的 .class 文件目录。
- Android
res/目录下的资源文件。 - Native 库的未压缩目录。
DirectoryInput 允许 Transform 以目录结构访问输入文件,方便对目录下的文件进行遍历和处理。- JarInput (Jar 包输入):表示一个 Jar 包形式的输入源。通常用于处理 已打包 的构建产物,例如:
- 项目依赖的 Jar 包 (Dependency JARs)。
- Android Archive (AAR) 文件中的 classes.jar。
- 插件或工具提供的 Jar 包。
JarInput 允许 Transform 将 Jar 包视为一个整体进行处理,或者解压 Jar 包后访问其内部的文件。TransformInput的重要性在于它抽象了构建输入的来源形式,使得 Transform 可以统一地处理不同类型的输入,并提供了增量构建的支持。
TransformInput 接口中关键的方法包括:getFile():获取输入的文件对象- 对于
DirectoryInput,通常是目录; - 对于
JarInput,则是 Jar 包文件。
getDirectory()(仅DirectoryInput适用):获取目录输入的根目录。
getJarFile()(仅JarInput适用):获取 Jar 包输入的 Jar 文件。
getChangedFiles()(仅在增量构建时有效):获取本次增量构建中发生变化的文件集合,用于支持增量构建。
isIncremental():指示当前输入是否为增量构建输入。
代码示例:
- 上述代码片段主要展示了如何根据不同的输入类型,进行不同的处理。主要是遍历
TransformInvocation的输入 (transformInvocation.getInputs()),并区分处理DirectoryInput和JarInput两种类型的输入。
- 对于
DirectoryInput,代码获取了目录 File 对象 (directoryInput.getFile()),并使用Files.walkFileTree遍历目录下的所有文件,并打印文件路径。
- 对于
JarInput,代码获取了 Jar 包 File 对象 (jarInput.getFile()),并打印 Jar 包路径 (实际应用中需要解压 Jar 包并处理内部文件)。
- 这段代码示例展示了如何根据不同的输入类型,进行不同的处理。
TransformOutput 接口:构建的输出目标
TransformOutput 接口代表了 Transform 的 输出目标,它定义了 Transform 生成的构建产物应该输出到哪里。与 TransformInput 类似,TransformOutput 也主要有两种具体的实现类型,与输入类型相对应:- DirectoryOutput (目录输出): 用于指定输出为 目录形式 的构建产物,通常与
DirectoryInput类型的输入相对应。例如,将修改后的 .class 文件输出到新的目录。
- JarOutput (Jar 包输出): 用于指定输出为 Jar 包形式 的构建产物,通常与
JarInput类型的输入相对应。例如,将处理后的 Jar 包输出到新的路径。
TransformOutput的作用是管理 Transform 的输出路径,确保输出的构建产物被正确地放置到 Gradle 构建系统的预期位置,并为后续的构建任务提供输入。
TransformOutput 接口中关键的方法包括:getFile():获取输出的文件对象,对于DirectoryOutput,通常是目录;对于JarOutput,则是 Jar 包文件。
getDirectory()(仅DirectoryOutput适用):获取目录输出的根目录。
getJarFile()(仅JarInput适用):获取 Jar 包输出的 Jar 文件。
Transform 的输出路径通常由 Gradle 构建系统进行管理,无需手动创建输出目录,只需通过
TransformOutput 提供的方法获取输出路径即可。Gradle 保证了输出路径的唯一性和正确性,避免了文件冲突和构建错误。代码示例
上述代码片段主要展示了如何遍历
TransformInvocation 的输出 (transformInvocation.getOutputs()),并区分处理 DirectoryOutput 和 JarOutput 两种类型的输出。- 对于
DirectoryOutput,代码获取了目录 File 对象 (directoryOutput.getFile()),并打印目录输出路径。
- 对于
JarOutput,代码获取了 Jar 包 File 对象 (jarOutput.getFile()),并打印 Jar 包输出路径。
注意:实际应用中,需要将转换后的文件写入outputDir、outputJar目录中。
TransformAction 接口:核心转换逻辑的定义
TransformAction 接口是 Transform 的 灵魂,它定义了 Transform 的 核心转换逻辑 (Transformation Logic)。 开发者需要实现 TransformAction 接口的 transform() 方法,在该方法中编写具体的转换代码,完成构建产物的转换操作。TransformAction 的 transform() 方法是 Transform 执行的核心入口点。其方法签名通常如下:
transform() 方法接收一个 TransformInvocation 对象作为参数,可以从 TransformInvocation 中获取输入 (getInputs())、输出 (getOutputs()) 和上下文信息 (getContext()),然后编写代码来读取输入文件,进行转换处理,并将结果写入到输出文件。在
transform() 方法中,可以自由地结合各种编程技术和工具实现一下特定需求,例如:- 字节码操作库 (Bytecode Manipulation Libraries):如 ASM、Javassist、Byte Buddy 等,用于修改 Java/Kotlin 字节码。
- 资源处理库 (Resource Processing Libraries):如 Android Resource Processing 工具 (AAPT2) 或自定义的资源解析和优化工具。
- 代码生成工具 (Code Generation Tools):如 JavaPoet、KotlinPoet 等,用于生成新的源代码或配置文件。
- 压缩和解压缩库 (Compression/Decompression Libraries):用于处理 Jar 包、Zip 文件等压缩格式。
TransformAction 的 transform() 方法是自定义 Transform 的核心代码所在,其逻辑的正确性和效率直接决定了 Transform 的功能和性能。开发过程中,需要根据具体的构建需求,精心设计和实现 transform() 方法中的转换逻辑。代码示例
- 上述代码片段展示了
TransformAction的transform()方法的基本结构。
transform()方法接收TransformInvocation对象作为参数。
- 在
transform()方法内部,主要是根据需要,编写具体的转换逻辑,包括: - 从
transformInvocation.getInputs()获取输入,并进行处理。 - 将转换后的产物通过
transformInvocation.getOutputs()输出。
- 示例代码中,仅仅打印了开始和结束日志,以及输入输出的遍历框架,实际应用中,需要将 真正的转换逻辑 填充到
// ... 处理输入 ...和// ... 输出转换后的产物 ...的注释位置。
Gradle Transform 的概念模型
Gradle Transform 的概念模型可以用以下几个关键要素来描述:
- 输入 (Input): Transform 接收
TransformInput对象作为输入,TransformInput可以是DirectoryInput(目录) 或JarInput(Jar 包) 两种形式,代表了需要被转换的构建产物。
- 转换逻辑 (Transformation Logic): 通过实现
TransformAction接口的transform()方法来定义具体的转换逻辑。转换逻辑负责读取输入,进行处理,并将结果写入输出。
- 输出 (Output): Transform 将转换后的构建产物通过
TransformOutput对象进行输出,TransformOutput同样可以是DirectoryOutput(目录) 或JarOutput(Jar 包) 两种形式,与输入类型相对应。
- TransformInvocation 上下文 (Context): 在 Transform 执行过程中,
TransformInvocation对象提供了必要的上下文信息,包括输入、输出、构建环境信息等,供TransformAction的transform()方法使用。
- Gradle 构建流程集成 (Gradle Build Flow Integration): 自定义的 Transform 需要通过 Android Gradle Plugin 提供的 API 注册到构建流程中,Gradle 会在合适的时机调度执行注册的 Transform,并将其纳入到整体的构建流程中。

总结
本文深入剖析了 Gradle Transform 的四大核心组件:
TransformInvocation、TransformInput、TransformOutput 和 TransformAction,并构建了 Gradle Transform 的概念模型。理解这些核心组件及其相互关系,是深入学习和应用 Gradle Transform 的关键。TransformInvocation:提供 Transform 执行的上下文环境。
TransformInput:定义 Transform 的输入源,可以是目录或 Jar 包。
TransformOutput:定义 Transform 的输出目标,与输入类型对应。
TransformAction:定义 Transform 的核心转换逻辑,是自定义 Transform 的核心代码所在。
参考
- Author:CoderWdd
- URL:https://www.wuinsights.top//article/81c0c866-215d-4807-9e6f-ba9647172d0e
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts