Gradle编译时所有Task信息打印

————————————————
版权声明:本文为CSDN博主「拿节」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhejiang9/article/details/105241392

Gradle工程编译的过程,就是执行目标task的过程,如果task存在依赖,则先执行依赖task,如此反复,直到触达无依赖的task

就这样,从无依赖task -> 目标task的执行链即建立,接着依次执行task即可,每个task之间数据传输,主要是通过task inputsoutputs描述文件来完成的

所以,gradle编译所有task信息的打印,应该包含

  1. 按task执行顺序打印task name
  2. 可以打印task的 inputsoutputs 数据
  3. 输出json信息保存到本地文件

我写了一个gradle脚本来完成上述信息输出:

import groovy.json.JsonOutput

//输出数据结构
class TaskItem {
    String name
    List<String> inputs = new ArrayList<>()
    List<String> outputs = new ArrayList<>()
}

class Dumper {
    //正则表达式,用于过滤要dump inputs和outputs的task
    //这里配置名称包含Jni的task,大家可以根据需要自行配置
    String taskInOutDirDumpFilter = "^.*Jni.*|^.*transform.*"
    String type
    File logOutDir
    List<TaskItem> taskList = new ArrayList<>()
    File logfile
    boolean isAvaliable = false

    Dumper(String type, File dir) {
        this.type = type
        this.logOutDir = dir
    }

    def makeLogFile() {
        logfile = new File(logOutDir, "taskDump-${type}.json")
        if (!logOutDir.exists()) {
            logOutDir.mkdirs()
        }
        if (logfile.exists()) {
            logfile.delete()
        }

        logfile.createNewFile()
    }

    def collectData(Task t) {
        t.doFirst {
            try {
                if (name == "pre${type}Build" && !isAvaliable) {
                    isAvaliable = true
                    makeLogFile()
                }
            } catch (Exception ex) {
                ex.printStackTrace()
                return
            }

            if (!isAvaliable) {
                return
            }

            TaskItem item = taskList.find {
                it.name == path
            }

            if (item != null) {
                return
            }

            item = new TaskItem()
            item.name = path

            taskList.add(item)

            def matcher = name =~ taskInOutDirDumpFilter
            if (matcher.size() > 0) {
                println "-------match task path = ${path}"

                t.inputs.each {
                    it.files.each {
                        item.inputs.add(it.absolutePath)
                    }
                }

                t.outputs.each {
                    it.files.each {
                        item.outputs.add(it.absolutePath)
                    }
                }
            }
        }
    }

    def dumpData2File() {
//        println " ------- dumpData2File " + logfile.getPath()
        def s = JsonOutput.toJson(taskList)

        logfile.write(s)
    }
}

Map<String, Dumper> dumperMap = new HashMap<>()
//数据dump目录
def dumpDir = new File(buildDir, "taskDump")
if (!dumpDir.exists()) {
    dumpDir.mkdirs()
}

rootProject.childProjects.each {
    it.value.afterEvaluate { Project project ->
        def isAndroidLibrary = project.plugins.hasPlugin("com.android.library")
        def isApplication = project.plugins.hasPlugin("com.android.application")
        if (!(isAndroidLibrary || isApplication)) {
            println("dumpTask -> is not android module.")
            return
        }
        def variants = isAndroidLibrary ? project.android.libraryVariants : project.android.applicationVariants

        variants.all { def variant ->
            // Create variant and target names
            def targetName = variant.name.capitalize()
            def dumper = dumperMap.get(targetName)

            if (dumper == null) {
                dumper = new Dumper(targetName, dumpDir)
                dumperMap.put(targetName, dumper)
            }

            project.tasks.each {
                dumper.collectData(it)
            }
        }
    }
}

gradle.buildFinished {
    dumperMap.each {
        if (it.value.isAvaliable) {
            try {
                it.value.dumpData2File()
            } catch (Exception ex) {
                println ex.getMessage()
            }
        }
    }
}

将脚本命名并保存到工程目录下,比如 dumptask.gradle,并保存道app module的根目录,接着再app module的build.gradle引入

apply from: “dumpTask.gradle”

接着执行

./gradlew assembleDebug

执行结束后, dump信息保存到如下文件

app/build/taskDump/taskDump-Debug.json

[
  ...
  {
    "contentHash": "c01a300bf2fd522b5c9c92944ade0672",
    "originalClassName": "TaskItem",
    "inputs": [],
    "outputs": [],
    "name": ":Media:prepareLintJarForPublish"
  },
  {
    "contentHash": "c01a300bf2fd522b5c9c92944ade0672",
    "originalClassName": "TaskItem",
    "inputs": [
      "/Users/likunlun/Android/Projects/DeveloperDocuments/AndroidStudy/Modules/Media/build/intermediates/stripped_native_libs/debug/out"
    ],
    "outputs": [
      "/Users/likunlun/Android/Projects/DeveloperDocuments/AndroidStudy/Modules/Media/build/intermediates/library_jni/debug/jni"
    ],
    "name": ":Media:copyDebugJniLibsProjectOnly"
  },
  ...
]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值