Using ClassTransformer with Task

在平常的开发过程中,我们可能需要在 Task 中依赖 Android Transform Pipeline 的产出物,例如:booster-task-analyseropen in new window 就是在 AnalyserTaskopen in new window 中对 Android Transform Pipeline 的产出物进行静态分析,针对这种应用场景,Booster 提供了一系列实用类和扩展方法:

通过 VariantProcessor 创建 Task

@AutoService(VariantProcessor::class)
class ScannerVariantProcessor : VariantProcessor {

    override fun process(variant: BaseVariant) {
        val project = variant.project
        val variantName = variant.name.capitalize()
        val transform = variant.extension.transforms.reversed().first {
            it.scopes.containsAll(TransformManager.SCOPE_FULL_PROJECT)
                    && it.inputTypes.contains(QualifiedContent.DefaultContentType.CLASSES)
        } ?: throw GradleException("No available transform")

        project.tasks.withType(TransformTask::class.java).find {
            it.name.endsWith(variantName) && it.transform == transform
        }?.let { transformTask ->
            project.tasks.create("scan${variantName}", ScannerTask::class.java) {
                it.variant = variant
                it.supplier = {
                    transformTask.outputs.files.single()
                }
            }.dependsOn(transformTask)
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

通过 VariantTransformHelper 复用 Transformer

open class ScannerTask : AbstractTask() {

    lateinit var variant: BaseVariant

    lateinit var supplier: () -> File

    @get:Input
    val variantName: String
        get() = variant.name

    @TaskAction
    fun scan() {
        VariantTransformHelper(variant, supplier())
            .transform(project.projectDir, AsmTransformer(ScannerTransformer()))
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

自定义 ClassTransformer

@AutoService(ClassTransformer::class)
class ScannerTransformer : ClassTransformer {

    override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
        // scanning klass
        klass
    }

}
1
2
3
4
5
6
7
8
9