中文字幕av高清_国产视频一二区_男女羞羞羞视频午夜视频_成人精品一区_欧美色视_在线视频这里只有精品

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > Gradle Transform到底是什么怎么用?

Gradle Transform到底是什么怎么用?

來源:千鋒教育
發布人:xqq
時間: 2023-10-13 12:00:43 1697169643

一、Gradle Transform到底是什么

Gradle Transform是Android官方提供給開發者在項目構建階段(.class -> .dex轉換期間)用來修改.class文件的一套標準API,即把輸入的.class文件轉變成目標字節碼文件,目前比較經典的應用是字節碼插樁、代碼注入等。

二、Gradle Transform怎么用

1、在build.gradle文件中添加Gradle插件依賴

buildscript {    dependencies {        classpath 'com.android.tools.build:gradle:x.x.x'        // 其他插件依賴    }}apply plugin: 'com.android.application' // 或其他所需插件

2、編寫Transform類

編寫Transform類,在其中實現對Java字節碼進行的修改。Transform類需要繼承自Transform接口并實現其兩個方法:

public class MyTransform extends Transform {   @Override   public String getName() {       return "myTransform";   }   @Override   public Set getInputTypes() {       return TransformManager.CONTENT_CLASS;   }   @Override   public Set getScopes() {       return TransformManager.SCOPE_FULL_PROJECT;   }   @Override   public boolean isIncremental() {       return false;   }   @Override   public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {       // 實現Transform邏輯   }}

3、配置Transform

在build.gradle文件中配置Transform,將其作為編譯期間的一個任務執行:

android {    ...    // 配置Transform    transformClassesWithMyTransformForDebug {        // 可選配置項,如下所示        // enable false        // ignoreWarnings true        // enableTransformForJar false    }}dependencies {    ...}

完成以上步驟后,Gradle會在編譯期間執行Transform對Java字節碼進行修改,從而實現各種自動生成代碼、字節碼增強等功能。

三、Transform編寫模板

1、無增量編譯

AspectJTransform.groovy代碼如下:

class AspectJTransform extends Transform {    final String NAME =  "JokerwanTransform"    @Override    String getName() {        return NAME    }    @Override    Set getInputTypes() {        return TransformManager.CONTENT_CLASS    }    @Override    Set getScopes() {        return TransformManager.SCOPE_FULL_PROJECT    }    @Override    boolean isIncremental() {        return false    }      @Override    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {        super.transform(transformInvocation)        // OutputProvider管理輸出路徑,如果消費型輸入為空,你會發現OutputProvider == null        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();        transformInvocation.inputs.each { TransformInput input ->            input.jarInputs.each { JarInput jarInput ->                // 處理Jar                processJarInput(jarInput, outputProvider)            }            input.directoryInputs.each { DirectoryInput directoryInput ->                // 處理源碼文件                processDirectoryInputs(directoryInput, outputProvider)            }        }    }    void processJarInput(JarInput jarInput, TransformOutputProvider outputProvider) {        File dest = outputProvider.getContentLocation(                jarInput.getFile().getAbsolutePath(),                jarInput.getContentTypes(),                jarInput.getScopes(),                Format.JAR)                        // to do some transform                // 將修改過的字節碼copy到dest,就可以實現編譯期間干預字節碼的目的了                FileUtils.copyFiley(jarInput.getFile(), dest)    }    void processDirectoryInputs(DirectoryInput directoryInput, TransformOutputProvider outputProvider) {        File dest = outputProvider.getContentLocation(directoryInput.getName(),                directoryInput.getContentTypes(), directoryInput.getScopes(),                Format.DIRECTORY)        // 建立文件夾                FileUtils.forceMkdir(dest)                // to do some transform                // 將修改過的字節碼copy到dest,就可以實現編譯期間干預字節碼的目的了                FileUtils.copyDirectory(directoryInput.getFile(), dest)    }}

2、有增量編譯

AspectJTransform.groovy代碼如下:

class AspectJTransform extends Transform {    final String NAME = "JokerWanTransform"    @Override    String getName() {        return NAME    }    @Override    Set getInputTypes() {        return TransformManager.CONTENT_CLASS    }    @Override    Set getScopes() {        return TransformManager.SCOPE_FULL_PROJECT    }    @Override    boolean isIncremental() {        return true    }    @Override    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {        super.transform(transformInvocation)        boolean isIncremental = transformInvocation.isIncremental()        // OutputProvider管理輸出路徑,如果消費型輸入為空,你會發現OutputProvider == null        TransformOutputProvider outputProvider = transformInvocation.getOutputProvider()        if (!isIncremental) {            // 不需要增量編譯,先清除全部            outputProvider.deleteAll()        }        transformInvocation.getInputs().each { TransformInput input ->            input.jarInputs.each { JarInput jarInput ->                // 處理Jar                processJarInputWithIncremental(jarInput, outputProvider, isIncremental)            }            input.directoryInputs.each { DirectoryInput directoryInput ->                // 處理文件                processDirectoryInputWithIncremental(directoryInput, outputProvider, isIncremental)            }        }    }    void processJarInputWithIncremental(JarInput jarInput, TransformOutputProvider outputProvider, boolean isIncremental) {        File dest = outputProvider.getContentLocation(                jarInput.getFile().getAbsolutePath(),                jarInput.getContentTypes(),                jarInput.getScopes(),                Format.JAR)        if (isIncremental) {            // 處理增量編譯            processJarInputWhenIncremental(jarInput, dest)        } else {            // 不處理增量編譯            processJarInput(jarInput, dest)        }    }    void processJarInput(JarInput jarInput, File dest) {        transformJarInput(jarInput, dest)    }    void processJarInputWhenIncremental(JarInput jarInput, File dest) {        switch (jarInput.status) {            case Status.NOTCHANGED:                break            case Status.ADDED:            case Status.CHANGED:                // 處理有變化的                transformJarInputWhenIncremental(jarInput.getFile(), dest, jarInput.status)                break            case Status.REMOVED:                // 移除Removed                if (dest.exists()) {                    FileUtils.forceDelete(dest)                }                break        }    }    void transformJarInputWhenIncremental(JarInput jarInput, File dest, Status status) {        if (status == Status.CHANGED) {            // Changed的狀態需要先刪除之前的            if (dest.exists()) {                FileUtils.forceDelete(dest)            }        }        // 真正transform的地方        transformJarInput(jarInput, dest)    }    void transformJarInput(JarInput jarInput, File dest) {            // to do some transform                // 將修改過的字節碼copy到dest,就可以實現編譯期間干預字節碼的目的了        FileUtils.copyFile(jarInput.getFile(), dest)    }    void processDirectoryInputWithIncremental(DirectoryInput directoryInput, TransformOutputProvider outputProvider, boolean isIncremental) {        File dest = outputProvider.getContentLocation(                directoryInput.getFile().getAbsolutePath(),                directoryInput.getContentTypes(),                directoryInput.getScopes(),                Format.DIRECTORY)        if (isIncremental) {            // 處理增量編譯            processDirectoryInputWhenIncremental(directoryInput, dest)        } else {            processDirectoryInput(directoryInput, dest)        }    }    void processDirectoryInputWhenIncremental(DirectoryInput directoryInput, File dest) {        FileUtils.forceMkdir(dest)        String srcDirPath = directoryInput.getFile().getAbsolutePath()        String destDirPath = dest.getAbsolutePath()        Map fileStatusMap = directoryInput.getChangedFiles()        fileStatusMap.each { Map.Entry entry ->            File inputFile = entry.getKey()            Status status = entry.getValue()            String destFilePath = inputFile.getAbsolutePath().replace(srcDirPath, destDirPath)            File destFile = new File(destFilePath)            switch (status) {                case Status.NOTCHANGED:                    break                case Status.REMOVED:                    if (destFile.exists()) {                        FileUtils.forceDelete(destFile)                    }                    break                case Status.ADDED:                case Status.CHANGED:                    FileUtils.touch(destFile)                    transformSingleFile(inputFile, destFile, srcDirPath)                    break            }        }    }    void processDirectoryInput(DirectoryInput directoryInput, File dest) {        transformDirectoryInput(directoryInput, dest)    }    void transformDirectoryInput(DirectoryInput directoryInput, File dest) {            // to do some transform                // 將修改過的字節碼copy到dest,就可以實現編譯期間干預字節碼的目的了        FileUtils.copyDirectory(directoryInput.getFile(), dest)    }    void transformSingleFile(File inputFile, File destFile, String srcDirPath) {        FileUtils.copyFile(inputFile, destFile)    }}

延伸閱讀1:TransformInput

TransformInput是指輸入文件的一個抽象,包括:

DitectoryInput集合:是指以源碼的方式參與項目編譯的所有目錄結構及其目錄下的源碼文件JarInput集合:是指以jar包方式參與項目編譯的所有本地jar包和遠程jar包(此處的jar包包括aar)
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
主站蜘蛛池模板: 国产精品久久久久影院色老大 | 天天干视频 | 成 人 a v天堂 | 久久99国产精一区二区三区 | 日韩一区中文字幕 | 狠久久 | 91性高湖久久久久久久久_久久99 | 草樱av| 久久国内精品 | 亚洲成人免费观看 | 国产精品美女www爽爽爽软件 | 国产91精品一区二区绿帽 | 中文字幕av亚洲精品一部二部 | 欧美手机在线 | 在线一区视频 | 欧美操大逼 | 国产日韩一区二区 | 国产精品三级在线 | 五月天电影网 | 色婷婷综合久久久久中文一区二区 | 日韩中文字幕一区二区 | 伊人精品影院 | 黄色毛片在线看 | 日本中文字幕一区二区有码在线 | 综合激情久久 | 日韩激情综合 | 亚洲免费小视频 | 毛片91| 国产亚洲aaa| 久久亚洲欧美日韩精品专区 | 日韩高清一区 | 在线免费av观看 | 91精品久久久久久久久中文字幕 | 久操不卡 | 精品国产一二 | 欧美视频一区二区三区在线观看 | 日本久久久一区二区三区 | 国产不卡视频一区二区三区 | 国产在线播放av | 九色91视频 | 国产高清在线观看 |