Gradle工程編譯的過程,就是執行目標task的過程,如果task存在依賴,則先執行依賴task,如此反覆,直到觸達無依賴的task
就這樣,從無依賴task -> 目標task的執行鏈即建立,接着依次執行task即可,每個task之間數據傳輸,主要是通過task inputs和outputs描述文件來完成的
所以,gradle編譯所有task信息的打印,應該包含
- 按task執行順序打印task name
- 可以打印task的inputs和outputs數據
- 將輸出json信息保存到本地文件
我寫了一個gradle腳本來完成上述信息輸出:
import groovy.json.JsonOutput
//輸出數據結構
class TaskItem{
String aname
List<String> inputs = new ArrayList<>()
List<String> outputs = new ArrayList<>()
}
class Dumper{
//正則表達式,用於過濾要dump inputs和outputs的task
//這裏配置名稱包含Jni的task,大家可以根據需要自行配置
String taskInOutDirDumpFilter = "^.*Jni.*"
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 (logfile.exists()) {
logfile.delete()
}
logfile.createNewFile()
}
def collectData(Task t){
t.doFirst {
if (name == "pre${type}Build" && !isAvaliable){
isAvaliable = true
makeLogFile()
}
if (!isAvaliable){
return
}
TaskItem item = taskList.find {
it.aname == path
}
if (item != null){
return
}
item = new TaskItem()
item.aname = 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 pp ->
def isAndroidLibrary = pp.plugins.hasPlugin("com.android.library")
def variants = isAndroidLibrary ? pp.android.libraryVariants : pp.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)
}
pp.tasks.each {
dumper.collectData(it)
}
}
}
}
gradle.buildFinished {
dumperMap.each {
if (it.value.isAvaliable){
it.value.dumpData2File()
}
}
}
將腳本命名並保存到工程目錄下,比如dumptask.gradle,並保存道app module的根目錄,接着再app module的build.gradle引入
apply from: "dumptask.gradle"
接着執行
./gradlew assembleDebug
執行結束後, dump信息保存到如下文件
app/build/taskdump/taskdump-Debug.json