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,下一節,就來說講若是經過更改字節碼達到面向切面編程的效果。

相關文章
相關標籤/搜索