黄视频网站在线免费观看-黄视频网站在线看-黄视频网站在线观看-黄视频网站免费看-黄视频网站免费观看-黄视频网站免费

千鋒教育-做有情懷、有良心、有品質(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到底是什么怎么用?

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

一、Gradle Transform到底是什么

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

二、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類,在其中實(shí)現(xiàn)對(duì)Java字節(jié)碼進(jìn)行的修改。Transform類需要繼承自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編寫模板

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管理輸出路徑,如果消費(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                // 將修改過的字節(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                // 將修改過的字節(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                // 將修改過的字節(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                // 將修改過的字節(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)您保持通訊暢通,專屬學(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類型的長(zhǎng)度是什么意思?

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

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ù)中的各類數(shù)據(jù)的描述集...詳情>>

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

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

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

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

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

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

2023-10-13 13:23:03
快速通道
国产精品123| 成人高清护士在线播放| 天天做日日爱夜夜爽| 天堂网中文字幕| 国产精品免费久久| 午夜久久网| 日韩字幕在线| 精品在线观看一区| 999久久66久6只有精品| 日本乱中文字幕系列| 国产伦精品一区二区三区无广告| 日本伦理黄色大片在线观看网站| 久久国产一久久高清| 九九精品久久久久久久久| 国产一区免费在线观看| 天天做日日爱夜夜爽| 九九国产| 九九九在线视频| 黄视频网站在线免费观看| 日本伦理黄色大片在线观看网站| 日韩中文字幕在线观看视频| 91麻豆爱豆果冻天美星空| 你懂的福利视频| 毛片高清| 999久久66久6只有精品| 亚洲 男人 天堂| 青草国产在线| 亚洲爆爽| 999久久狠狠免费精品| 色综合久久天天综合| 韩国毛片免费| 韩国妈妈的朋友在线播放| 国产成a人片在线观看视频| 国产视频久久久| 亚洲 欧美 成人日韩| 国产网站在线| 精品在线观看一区| 亚洲天堂免费观看| 日本在线不卡视频| 国产亚洲精品aaa大片| 午夜精品国产自在现线拍| 亚洲精品久久玖玖玖玖| 欧美一区二区三区性| 美女免费精品高清毛片在线视| 日本在线不卡视频| 免费国产在线观看| 欧美激情在线精品video| 国产伦理精品| 免费一级片在线观看| 日韩女人做爰大片| 国产成人精品影视| 黄色短视屏| 国产不卡福利| 欧美电影免费| 九九精品影院| 美女免费毛片| 国产麻豆精品视频| 99热热久久| 日韩在线观看视频黄| 久久国产精品永久免费网站| 国产国产人免费视频成69堂| 高清一级片| 可以免费看污视频的网站| 午夜精品国产自在现线拍| 成人a大片高清在线观看| 日韩专区在线播放| 天天色成人| 日本伦理网站| 午夜在线观看视频免费 成人| 亚洲 男人 天堂| 久久99青青久久99久久| 久久久成人网| 久草免费在线视频| 精品国产亚一区二区三区| 欧美电影免费看大全| 国产网站免费在线观看| 日本在线www| 亚欧视频在线| 一级毛片视频免费| 日韩一级精品视频在线观看| 人人干人人草| 天天做日日爱| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 国产91精品一区| 亚洲爆爽| 可以免费在线看黄的网站| 91麻豆爱豆果冻天美星空| 九九热国产视频| 色综合久久久久综合体桃花网| 九九久久99综合一区二区| 黄视频网站在线看| 久久成人性色生活片| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 亚州视频一区二区| 国产成人精品一区二区视频| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 免费国产在线观看| 九九精品久久久久久久久| 国产视频网站在线观看| 台湾毛片| 国产一区二区精品在线观看| 一级片片| 青青青草影院| 99色吧| 国产麻豆精品免费密入口| 精品视频免费看| 午夜在线亚洲| 亚洲爆爽| 国产不卡高清在线观看视频| 99久久精品国产免费| 久久精品免视看国产明星| 精品视频一区二区三区免费| 国产高清视频免费| 精品视频免费看| 97视频免费在线观看| 成人高清免费| 久久99这里只有精品国产| 欧美激情一区二区三区视频高清| 国产视频久久久久| a级黄色毛片免费播放视频| 国产伦精品一区二区三区无广告| 成人高清视频在线观看| 亚洲精品中文字幕久久久久久| 欧美a级成人淫片免费看| 久久久成人网| 成人免费网站视频ww| 久久精品店| 欧美一级视频免费观看| 精品视频一区二区三区| 日韩免费在线视频| 日本特黄特色aa大片免费| 国产成人精品综合| 色综合久久久久综合体桃花网| 麻豆网站在线免费观看| 成人a大片高清在线观看| 一级女性全黄久久生活片| 国产美女在线观看| 国产一级生活片| 四虎影视库国产精品一区| 中文字幕97| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 欧美激情影院| a级毛片免费全部播放| 日韩在线观看免费完整版视频| 欧美激情影院| 国产不卡高清在线观看视频| 美女免费精品视频在线观看| 免费一级片网站| 黄色免费三级| 91麻豆国产| 欧美国产日韩精品| 国产极品白嫩美女在线观看看| 中文字幕一区二区三区 精品| 精品国产三级a| 成人高清视频免费观看| 国产高清视频免费观看| 日本伦理片网站| 日韩欧美一及在线播放| 99久久精品费精品国产一区二区| 国产一区二区精品久久91| 黄色免费网站在线| 成人a级高清视频在线观看| 日韩中文字幕在线播放| 台湾毛片| 国产极品白嫩美女在线观看看| 国产精品自拍一区| 国产一区二区精品久久| 国产视频久久久久| 国产精品自拍一区| 国产精品1024永久免费视频| 精品国产香蕉在线播出| 国产不卡精品一区二区三区| 国产不卡在线播放| 久久精品大片| 天天做人人爱夜夜爽2020毛片| 国产国语在线播放视频| 黄视频网站在线观看| 成人免费观看的视频黄页| 亚洲第一视频在线播放| 国产精品12| 久草免费资源| 黄视频网站免费| 欧美一级视频免费观看| a级毛片免费观看网站| 日本免费乱理伦片在线观看2018| 99热精品在线| 成人免费观看的视频黄页| 亚欧视频在线| 九九国产| 欧美激情一区二区三区在线| 精品视频一区二区三区免费| 日韩专区亚洲综合久久| 欧美大片a一级毛片视频| 国产91精品一区| 韩国毛片免费大片| 国产一区二区精品| 久久国产精品只做精品| 黄色福利片| 久久精品店| 国产激情视频在线观看|