久久精品国产亚洲高清|精品日韩中文乱码在线|亚洲va中文字幕无码久|伊人久久综合狼伊人久久|亚洲不卡av不卡一区二区|精品久久久久久久蜜臀AV|国产精品19久久久久久不卡|国产男女猛烈视频在线观看麻豆

    1. <style id="76ofp"></style>

      <style id="76ofp"></style>
      <rt id="76ofp"></rt>
      <form id="76ofp"><optgroup id="76ofp"></optgroup></form>
      1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

        手機(jī)站
        千鋒教育

        千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

        千鋒教育

        掃一掃進(jìn)入千鋒手機(jī)站

        領(lǐng)取全套視頻
        千鋒教育

        關(guān)注千鋒學(xué)習(xí)站小程序
        隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

        當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > Gradle Transform到底是什么怎么用?

        Gradle Transform到底是什么怎么用?

        來(lái)源:千鋒教育
        發(fā)布人:xqq
        時(shí)間: 2023-10-13 12:00:43 1697169643

        一、Gradle Transform到底是什么

        Gradle Transform是Android官方提供給開(kāi)發(fā)者在項(xiàng)目構(gòu)建階段(.class -> .dex轉(zhuǎn)換期間)用來(lái)修改.class文件的一套標(biāo)準(zhǔn)API,即把輸入的.class文件轉(zhuǎn)變成目標(biāo)字節(jié)碼文件,目前比較經(jīng)典的應(yīng)用是字節(jié)碼插樁、代碼注入等。

        二、Gradle Transform怎么用

        1、在build.gradle文件中添加Gradle插件依賴(lài)

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

        2、編寫(xiě)Transform類(lèi)

        編寫(xiě)Transform類(lèi),在其中實(shí)現(xiàn)對(duì)Java字節(jié)碼進(jìn)行的修改。Transform類(lèi)需要繼承自Transform接口并實(shí)現(xiàn)其兩個(gè)方法:

        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 {       // 實(shí)現(xiàn)Transform邏輯   }}

        3、配置Transform

        在build.gradle文件中配置Transform,將其作為編譯期間的一個(gè)任務(wù)執(zhí)行:

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

        完成以上步驟后,Gradle會(huì)在編譯期間執(zhí)行Transform對(duì)Java字節(jié)碼進(jìn)行修改,從而實(shí)現(xiàn)各種自動(dòng)生成代碼、字節(jié)碼增強(qiáng)等功能。

        三、Transform編寫(xiě)模板

        1、無(wú)增量編譯

        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管理輸出路徑,如果消費(fèi)型輸入為空,你會(huì)發(fā)現(xiàn)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                // 將修改過(guò)的字節(jié)碼copy到dest,就可以實(shí)現(xiàn)編譯期間干預(yù)字節(jié)碼的目的了                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                // 將修改過(guò)的字節(jié)碼copy到dest,就可以實(shí)現(xiàn)編譯期間干預(yù)字節(jié)碼的目的了                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管理輸出路徑,如果消費(fèi)型輸入為空,你會(huì)發(fā)現(xiàn)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的狀態(tài)需要先刪除之前的            if (dest.exists()) {                FileUtils.forceDelete(dest)            }        }        // 真正transform的地方        transformJarInput(jarInput, dest)    }    void transformJarInput(JarInput jarInput, File dest) {            // to do some transform                // 將修改過(guò)的字節(jié)碼copy到dest,就可以實(shí)現(xiàn)編譯期間干預(yù)字節(jié)碼的目的了        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                // 將修改過(guò)的字節(jié)碼copy到dest,就可以實(shí)現(xiàn)編譯期間干預(yù)字節(jié)碼的目的了        FileUtils.copyDirectory(directoryInput.getFile(), dest)    }    void transformSingleFile(File inputFile, File destFile, String srcDirPath) {        FileUtils.copyFile(inputFile, destFile)    }}

        延伸閱讀1:TransformInput

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

        DitectoryInput集合:是指以源碼的方式參與項(xiàng)目編譯的所有目錄結(jié)構(gòu)及其目錄下的源碼文件JarInput集合:是指以jar包方式參與項(xiàng)目編譯的所有本地jar包和遠(yuǎn)程jar包(此處的jar包包括aar)
        聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
        10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
        請(qǐng)您保持通訊暢通,專(zhuān)屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
        免費(fèi)領(lǐng)取
        今日已有369人領(lǐng)取成功
        劉同學(xué) 138****2860 剛剛成功領(lǐng)取
        王同學(xué) 131****2015 剛剛成功領(lǐng)取
        張同學(xué) 133****4652 剛剛成功領(lǐng)取
        李同學(xué) 135****8607 剛剛成功領(lǐng)取
        楊同學(xué) 132****5667 剛剛成功領(lǐng)取
        岳同學(xué) 134****6652 剛剛成功領(lǐng)取
        梁同學(xué) 157****2950 剛剛成功領(lǐng)取
        劉同學(xué) 189****1015 剛剛成功領(lǐng)取
        張同學(xué) 155****4678 剛剛成功領(lǐng)取
        鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
        董同學(xué) 138****2867 剛剛成功領(lǐng)取
        周同學(xué) 136****3602 剛剛成功領(lǐng)取
        相關(guān)推薦HOT
        MySQL數(shù)據(jù)庫(kù)char類(lèi)型的長(zhǎng)度是什么意思?

        一、MySQL數(shù)據(jù)庫(kù)char類(lèi)型的長(zhǎng)度是什么意思MySQL數(shù)據(jù)庫(kù)char類(lèi)型的長(zhǎng)度是指該字段所占用的字節(jié)數(shù)。char數(shù)據(jù)類(lèi)型是MySQL中固定長(zhǎng)度的字符類(lèi)型。 我...詳情>>

        2023-10-13 13:51:32
        “數(shù)據(jù)庫(kù)”領(lǐng)域里面的“數(shù)據(jù)字典”到底是什么?

        一、“數(shù)據(jù)庫(kù)”領(lǐng)域里面的“數(shù)據(jù)字典”到底是什么數(shù)據(jù)字典是一個(gè)存放有數(shù)據(jù)庫(kù)所用的有關(guān)信息,在數(shù)據(jù)庫(kù)設(shè)計(jì)的初期將數(shù)據(jù)庫(kù)中的各類(lèi)數(shù)據(jù)的描述集...詳情>>

        2023-10-13 13:49:07
        微博feed系統(tǒng)的推模式和拉模式的架構(gòu)是怎樣的?

        一、微博feed系統(tǒng)的推模式架構(gòu)1、發(fā)布服務(wù)負(fù)責(zé)生成用戶(hù)的消息,將消息推送到數(shù)據(jù)發(fā)布中心。2、推送服務(wù)在接收到新消息后,根據(jù)消息的類(lèi)型和內(nèi)容...詳情>>

        2023-10-13 13:28:55
        Oracle數(shù)據(jù)庫(kù)運(yùn)行越來(lái)越慢,應(yīng)該怎么優(yōu)化?

        一、Oracle數(shù)據(jù)庫(kù)運(yùn)行越來(lái)越慢的優(yōu)化方法1、應(yīng)用層優(yōu)化應(yīng)用程序的設(shè)計(jì)和開(kāi)發(fā)中,可以采用合理的數(shù)據(jù)查詢(xún)語(yǔ)句來(lái)減少數(shù)據(jù)庫(kù)的 I/O 操作次數(shù),例如...詳情>>

        2023-10-13 13:27:44
        mysql當(dāng)數(shù)據(jù)同時(shí)屬于多個(gè)分類(lèi)時(shí),該怎么查詢(xún)?

        一、mysql當(dāng)數(shù)據(jù)同時(shí)屬于多個(gè)分類(lèi)時(shí),該怎么查詢(xún)1、使用 AND 連接符可以將多個(gè)分類(lèi)條件使用 AND 連接符連接起來(lái),下面是代碼示例:SELECT * FRO...詳情>>

        2023-10-13 13:23:03
        快速通道
        梁山县| 清远市| 丽江市| 呼和浩特市| 吉林省| 灵石县| 乐亭县| 贺州市| 青田县| 伊川县| 尉犁县| 突泉县| 建始县| 文山县| 博罗县| 武强县| 县级市| 夏邑县| 中超| 东莞市| 毕节市| 邯郸县| 泰和县| 奉贤区| 平原县| 平远县| 嘉荫县| 称多县| 邯郸县| 循化| 札达县| 香港 | 望城县| 互助| 商都县| 梅河口市| 通化县| 翁牛特旗| 宁远县| 新蔡县| 舒兰市|