Gradle插件系列(二)—— 配置本身的Transform

在上一篇,咱们已经知道了如何建立一个简单的插件,这一节将在此基础上继续说说如何配置本身的Transformjava

1 转换器 Transform

转换器Transform是由Google提供,让开发者能够在编译后,打包前这段时期,进行额外干预操做,从而提供操做字节码的时机。android

2 建立 Transform

建立自定义的FreeCoderTransform类,而后继承至Transform编程

public class FreeCoderTransform extends Transform {
    // 1
    @Override
    public String getName() { 
        return "freecoder";
    }

    // 2
    @Override
    public Set<QualifiedContent.ContentType> getInputTypes() {
        return TransformManager.CONTENT_CLASS;
    }

    // 3
    @Override
    public Set<? super QualifiedContent.Scope> getScopes() {
        return TransformManager.SCOPE_FULL_PROJECT;
    }

    // 4
    @Override
    public boolean isIncremental() {
        return false;
    }

    // 5
    @Override
    public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
        Collection<TransformInput> inputs = transformInvocation.getInputs();
        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();

        inputs.forEach(transformInput -> {
            transformInput.getJarInputs().forEach(jarInput -> {
                File dest = outputProvider.getContentLocation(jarInput.getName(), jarInput.getContentTypes(), jarInput.getScopes(), Format.JAR);
                try {
                    FileUtils.copyFile(jarInput.getFile(), dest);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            transformInput.getDirectoryInputs().forEach(directoryInput -> {
                File dest = outputProvider.getContentLocation(directoryInput.getName(), directoryInput.getContentTypes(), directoryInput.getScopes(), Format.DIRECTORY);
                try {
                    FileUtils.copyFile(directoryInput.getFile(), dest);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        });
    }
}
复制代码

标记1处:对应自定义TransformTask名称,同步完成后,会显示在Gradle控制面板上,好比:transformClassesWithXXXForDebugmarkdown

标记二、3处:定义了咱们将要操做的编译过程当中具体哪些类型的文件,其中 2 的类型:app

CONTENT_CLASS://class 文件

CONTENT_JARS: //jar包,包括class文件与resource资源文件

CONTENT_RESOURCES // resource资源文件

CONTENT_NATIVE_LIBS // 本地libs

CONTENT_DEX // dex文件

CONTENT_DEX_WITH_RESOURCES // dex文件与resource资源文件
复制代码

标记 3 处:表示做用的项目范围,SCOPE_FULL_PROJECT表示整个项目。ide

标记 4 处:表示是否支持增量编译。post

标记 5 处:这里是个核心方法,须要覆盖重写,而且按Google提供的输出目录outputProvider上输出,不然将这个Transform引入会报错。lua

transformInvocation.getInputs()获取编译后的全部class文件,transformInvocation.getOutputProvider()获取Google提供的输出目录,咱们把这些编译后的文件作完处理后,而后再扔向该目录,最终参与到打dex包的过程。spa

然后就是简单的复制工做,至于处理,咱们下一节讲,这个过程能够实现面向切面的编程。插件

3 引入 Transform

以下:(接上一节代码)

public class FreeCoderPlugin implements Plugin<Project> {
    @Override
    public void apply(Project project) {
        final FreeCoderExtension extension = project.getExtensions()
                .create("freecoder", FreeCoderExtension.class);
        project.afterEvaluate(innerProject -> System.out.println("extension: " + extension.name));

        // 建立转换器
        FreeCoderTransform freeCoder = new FreeCoderTransform();
        // 1
        BaseExtension baseExtension = project.getExtensions().getByType(BaseExtension.class);
        // 2
        baseExtension.registerTransform(freeCoder);
    }
}
复制代码

标记1处:BaseExtension指的就是Android打包过程当中,com.android.application这个插件所包含的扩展,方便开发者在打包过程当中进行相应的干预。

标记2处:把咱们的Transform注册进入该扩展中。

到此为止,咱们就配置好了本身的Transform,下一节,就来说讲若是经过更改字节码达到面向切面编程的效果。

相关文章
相关标签/搜索