Transform介绍 - 源码分析(3)

1. Transform 与 Task 的关系

Project是由Task组成,每个 Task 负责完成一个基本工作,例如 javac 编译 task,transform 也是依靠 Task(TransformTask ) 执行的,在配置阶段, Gradle 会为注册的 Transform 创建对应的 Task(TransformTask )

而 Task 的依赖关系是通过 TransformTask 的输入输出关系隐式确定的,TransformManager 通过 TransformStream 链接各个 TransformTask 的输入输出,进而控制 Transform 的依赖关系顺序

我们先从 Plugin 的注册 transform 开始:

// MyPlugin.groovy
void apply(Project project){
    def baseExt = project.extensions.getByType(BaseExtension.class)
    baseExt.registerTransform(new MyTransform2(project))
}

接着进入 BaseExtension 看看,这个类维护了所有 Transform

// com.android.build.gradle\BaseExtension.kt
fun registerTransform(transform: Transform, vararg dependencies: Any) {
    _transforms.add(transform)
    _transformDependencies.add(listOf(dependencies))
}

override val transforms: List<Transform>
        get() = ImmutableList.copyOf(_transforms)

查看 transforms变量的调用,找到LibraryTaskManager.java,我们看看该类

// com.android.build.gradle.internal\LibraryTaskManager.java
public class LibraryTaskManager extends TaskManager<LibraryVariantBuilderImpl, LibraryVariantImpl> {
    @Override
    protected void doCreateTasksForVariant(..){
        ...
         // ----- External Transforms -----
        // apply all the external transforms.
        List<Transform> customTransforms = extension.getTransforms();
    }
}

发现在 doCreateTasksForVariant 方法中有调用,该类的父类是 TaskManager,感兴趣的可以去翻翻它们看看,我这里将方法调用链进行列举

// com.android.build.gradle.internal
TaskManager.java
-> doCreateTasksForVariant() // 【注1】
-> createTasksForVariant()
-> createTasks()
// com.android.build.gradle.internal.plugins
BasePlugin.java
-> createAndroidTasks()
-> createTasks() // 【注2】project.afterEvaluate()中调用 createAndroidTasks()
-> basePluginApply()
-> apply()// 【注3】
// com.android.build.gradle.internal.plugins
LibraryPlugin.java // 【注4】

2. Transform 的注册

【注1】执行 doCreateTasksForVariant 抽象方法,具体到实现类为LibraryTaskManager,Library 模块仅只支持使用 Scope.PROJECT 作用域。自定义插件不涉及ApplicationTaskManager

// com.android.build.gradle.internal\LibraryTaskManager.java
public class LibraryTaskManager extends TaskManager<LibraryVariantBuilderImpl, LibraryVariantImpl> {
    ...
    @Override
    protected void doCreateTasksForVariant(..){
        ...
         // ----- External Transforms -----
        // apply all the external transforms.
        List<Transform> customTransforms = extension.getTransforms();
        ...
        for (int i = 0, count = customTransforms.size(); i < count; i++) {
            Transform transform = customTransforms.get(i);
            // Library 模块仅只支持使用 Scope.PROJECT 作用域
            Sets.SetView<? super Scope> difference =
            		Sets.difference(transform.getScopes(), TransformManager.PROJECT_ONLY);
            ...
            // 将 transfrom 添加到 TransformManager 中
            transformManager.addTransform(
                    taskFactory,
                    libraryVariant,
                    transform,...)
        }
    }
}


我们进入 TransformManager 看看添加 transform 的方法,看到 TransformTask 的 TaskName 有相应的规范transform[InputTypes]with[name]For[componentName]

// com.android.build.gradle.internal.pipeline
public class TransformManager extends FilterableStreamCollection {
    ...
    public <T extends Transform> Optional<TaskProvider<TransformTask>> addTransform(..){
        ...
        // TaskName = transform[InputTypes]with[name]For[componentName]
        String taskName = creationConfig.computeTaskName(getTaskNamePrefix(transform), "");
        ...
    }
    
    ...
    // TaskName 前缀 :transform[InputTypes]with[name]For
    static String getTaskNamePrefix(@NonNull Transform transform) {
        StringBuilder sb = new StringBuilder(100);
        sb.append("transform");
        sb.append(
                transform
                        .getInputTypes()
                        .stream()
                        .map(
                                inputType ->
                                        CaseFormat.UPPER_UNDERSCORE.to(
                                                CaseFormat.UPPER_CAMEL, inputType.name()))
                        .sorted() // Keep the order stable.
                        .collect(Collectors.joining("And")));
        sb.append("With");
        StringHelper.appendCapitalized(sb, transform.getName());
        sb.append("For");
        return sb.toString();
    }
}

3. TransformTask 的输入输出

public abstract class TransformTask extends StreamBasedTask {
    //...
 	@Input
    @NonNull
    public Set<QualifiedContent.ContentType> getInputTypes() {
        return transform.getInputTypes();
    }
    ...
    @OutputDirectory
    @Optional
    @NonNull
    public abstract DirectoryProperty getOutputDirectory()
}

通过 @Input 和 @OutputDirectory 将 Transform 与 TransformTask 进行关联

再看看 transform 方法,每个 TransformTask 内部都包含一个 CreationAction,执行 TransformTask 就是执行该 Action,用户通过 @TaskAction 添加默认 Action

  @TaskAction
    void transform(final IncrementalTaskInputs incrementalTaskInputs)
            throws IOException, TransformException, InterruptedException {
        ...
        u analyticsService = getAnalyticsService().get();
        ...
        analyticsService.recordBlock(
                ExecutionType.TASK_TRANSFORM,
                executionInfo,
                getProjectPath().get(),
                getVariantName(),
                new Recorder.VoidBlock() {
                    @Override
                    public void call() {
                        ...
                         transform.transform(
                                new TransformInvocationBuilder(context)
                                        .addInputs(consumedInputs.getValue())
                                        .addReferencedInputs(referencedInputs.getValue())
                                        .addSecondaryInputs(changedSecondaryInputs.getValue())
                                        .addOutputProvider(
                                                outputStream != null
                                                        ? outputStream.asOutput()
                                                        : null)
                                        .setIncrementalMode(isIncremental.getValue())
                                        .build());
                    }
                }
        
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值