You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Gradle实现所有任务完成后自动下载音频并播放

问题

我希望在Android Gradle的所有任务执行完成后播放音乐,但不清楚如何将其与最后一个任务/事件关联。目前我已实现手动执行下载并播放音乐的功能,相关代码如下(基本可运行):

def tempSound = "/tmp/gradleBuildFinished.wav"

task downloadMusic {
    doLast {
        println "downloadMusic"

        def sounds = [
                "http://www.xxx.zzz/hos1.wav",
                "http://www.xxx.zzz/hos2.wav",
        ]

        def r = new Random()
        def soundIndex = r.nextInt(sounds.size())

        println "Deleting temp sound: " + delete(tempSound)

        exec {
            commandLine("bash", "-c", "curl " + sounds.get(soundIndex) + " > " + tempSound)
        }
    }
}

task playMusic {
    dependsOn downloadMusic

    doLast {
        println "playMusic"

        assert file(tempSound).exists()

        ("afplay " + tempSound).execute()
    }
}

gradle.buildFinished{
    // how to execute playMusic? It will trigger when all tasks are done, right?
}

想请教如何在gradle.buildFinished闭包中执行playMusic任务?

解决方案

Gradle的buildFinished回调确实在所有任务执行完成后触发,但此时任务执行阶段已经结束,无法直接调用playMusic.execute()触发任务执行(会抛出异常)。以下是两种可行的实现方式:

方法1:提取逻辑为独立方法,直接在buildFinished中调用

把下载和播放的核心逻辑抽成独立方法,直接在buildFinished里执行,跳过任务机制的限制:

def tempSound = "/tmp/gradleBuildFinished.wav"

// 提取下载逻辑为方法
def downloadRandomSound() {
    println "downloadMusic"

    def sounds = [
            "http://www.xxx.zzz/hos1.wav",
            "http://www.xxx.zzz/hos2.wav",
    ]

    def r = new Random()
    def soundIndex = r.nextInt(sounds.size())

    println "Deleting temp sound: " + delete(tempSound)

    exec {
        commandLine("bash", "-c", "curl " + sounds.get(soundIndex) + " > " + tempSound)
    }
}

// 提取播放逻辑为方法
def playDownloadedSound() {
    println "playMusic"

    assert file(tempSound).exists()

    ("afplay " + tempSound).execute()
}

// 保留原任务(方便手动测试)
task downloadMusic {
    doLast {
        downloadRandomSound()
    }
}

task playMusic {
    dependsOn downloadMusic

    doLast {
        playDownloadedSound()
    }
}

// 构建完成后自动执行下载和播放
gradle.buildFinished {
    try {
        downloadRandomSound()
        playDownloadedSound()
    } catch (Exception e) {
        println "播放音乐失败: ${e.message}"
    }
}

方法2:通过任务依赖让playMusic自动在最后执行

利用Gradle任务图机制,让playMusic成为所有执行任务的最终依赖,确保它在最后运行:

def tempSound = "/tmp/gradleBuildFinished.wav"

task downloadMusic {
    doLast {
        println "downloadMusic"

        def sounds = [
                "http://www.xxx.zzz/hos1.wav",
                "http://www.xxx.zzz/hos2.wav",
        ]

        def r = new Random()
        def soundIndex = r.nextInt(sounds.size())

        println "Deleting temp sound: " + delete(tempSound)

        exec {
            commandLine("bash", "-c", "curl " + sounds.get(soundIndex) + " > " + tempSound)
        }
    }
}

task playMusic {
    dependsOn downloadMusic

    doLast {
        println "playMusic"

        assert file(tempSound).exists()

        ("afplay " + tempSound).execute()
    }
}

// 任务图准备就绪后,配置playMusic为所有任务的后置依赖
gradle.taskGraph.whenReady { graph ->
    graph.allTasks.each { task ->
        if (task != playMusic) {
            playMusic.mustRunAfter task
        }
    }
    // 确保playMusic被加入执行队列
    if (!graph.hasTask(playMusic)) {
        graph.addTask(playMusic)
    }
}

注意事项

  • afplay是macOS专属的音频播放命令,Windows环境可替换为start,Linux环境可替换为aplay。
  • 网络下载可能出现失败,建议添加异常捕获逻辑,避免影响构建完成后的体验。

内容的提问来源于stack exchange,提问作者deadfish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:15:39