自定义Transform
本文章研究所使用的示例代码:AndroidPluginDemo
基础概念
| 术语 | 说明 |
|---|---|
| TransformInput | 所谓Transform就是对输入的class文件转变成目标字节码文件,TransformInput就是这些输入文件的抽象。目前它包括两部分:DirectoryInput集合与JarInput集合。 |
| DirectoryInput | 它代表着以源码方式参与项目编译的所有目录结构及其目录下的源码文件,可以借助于它来修改输出文件的目录结构、目标字节码文件。 |
| JarInput | 它代表着以jar包方式参与项目编译的所有本地jar包或远程jar包,可以借助于它来动态添加jar包。 |
| TransformOutputProvider | 它代表的是Transform的输出,例如可以通过它来获取输出路径。 |
Transform API
使用Transform API主要是写一个类继承Transform,并把该Transform注入到打包过程中。注入Transform很简单,先获取com.android.build.gradle.BaseExtension对象,然后调用它的registerTransform()方法。
public class CustomPlugin implements Plugin<Project> {
@Override
public void apply(@NotNull Project project) {
project.getExtensions().findByType(BaseExtension.class)
.registerTransform(new CustomTransform(project));
}
}
Transform常用API:
| 方法 | 说明 |
|---|---|
| String getName() | 用于指明本Transform的名字,也是代表该Transform的task的名字。 |
| Set<QualifiedContent.ContentType> getInputTypes() | 用于指明Transform的输入类型,可以作为输入过滤的手段。 |
| Set<? super QualifiedContent.Scope> getScopes() | 用于指明Transform的作用域。 |
| boolean isIncremental() | 用于指明是否是增量构建。 |
| void transform(TransformInvocation invocation) | 执行Transform方法,Transform处理逻辑的地方。 |
| boolean applyToVariant(@NonNull VariantInfo variant) | 是否应将此Transform应用于给定的variant,可以区分渠道使用Transform。 |
ContentType
ContentType是一个接口,默认有一个枚举类型DefaultContentType实现了ContentType,包含有CLASSES和RESOURCES类型。
| 类型 | 说明 |
|---|---|
| CLASSES | 表示的是在jar包或者文件夹中的.class文件。 |
| RESOURCES | 表示的是标准的Java资源文件。 |
Android Plugin扩展的ContentType -> ExtendedContentType:
| 类型 | 说明 |
|---|---|
| DEX | The content is dex files. |
| NATIVE_LIBS | Content is a native library. |
| CLASSES_ENHANCED | Instant Run ‘$override’ classes, which contain code of new method bodies.此流还包含用于应用HotSwap更改的AbstractPatchesLoaderImpl类。 |
| DATA_BINDING | The content is an artifact exported by the data binding compiler. |
| JAVA_SOURCES | The content is Java source file. @Deprecated don’t use! |
| DEX_ARCHIVE | The content is a dex archive. It contains a single DEX file per class. |
Scope 作用范围
| Scope类型 | 说明 |
|---|---|
| PROJECT | 只处理当前的项目(模块) |
| SUB_PROJECTS | 只处理子项目(模块) |
| EXTERNAL_LIBRARIES | 只处理外部的依赖库 |
| TESTED_CODE | 只处理测试代码 |
| PROVIDED_ONLY | 只处理provided-only的依赖库 |
| PROJECT_LOCAL_DEPS | 只处理当前项目的本地依赖,例如jar, aar(过期,被EXTERNAL_LIBRARIES替代) |
| SUB_PROJECTS_LOCAL_DEPS | 只处理子项目的本地依赖,例如jar, aar(过期,被EXTERNAL_LIBRARIES替代) |
Transform中的getInputTypes()方法和getScopes()方法返回的是Set集合,因此这些类型是可以进行组合的。在TransformManager中就包含了多种Set集合。
package com.android.build.gradle.internal.pipeline;
/**
* Manages the transforms for a variant.
*
* <p>The actual execution is handled by Gradle through the tasks.
* Instead it's a means to more easily configure a series of transforms that consume each other's
* inputs when several of these transform are optional.
*/
public class TransformManager extends FilterableStreamCollection {
private static final boolean DEBUG = true;
private static final String FD_TRANSFORMS = "transforms";
public static

本文详细介绍了如何自定义Transform,并在Android项目中使用Gradle插件进行集成。通过Transform API,我们可以操作ContentType和Scope,实现增量编译。文章探讨了isIncremental方法、JarInput和DirectoryInput的使用,以及如何处理TransformInvocation中的输入和输出。在不支持增量编译的情况下,需要清除旧的输出目录。通过自定义Transform,可以在编译过程中添加特定的处理逻辑,如日志记录或代码修改。
最低0.47元/天 解锁文章
940

被折叠的 条评论
为什么被折叠?



