Gradle任务使用adb来安装apk没有被执行

时间:2017-01-31 16:30:10

标签: android gradle groovy android-emulator adb

我正在编写一个gradle任务,在运行espresso测试之前安装apk到模拟器。

这是我到目前为止的任务。

task installButlerApk {

doLast {
    println "Verifying test-butler installation in emulators"

    final adb = "$android.sdkDirectory.absolutePath/platform-tools/adb"

    final String[] split = ["$adb", "devices", "-l"].execute().text.split("\\r?\\n")

    split.each {

        if (it.isEmpty())
            return;

        println "Emulator: $it"

        final emu = it.split("\\s")[0]
        checks whether the APK is already installed
        if (["$adb", "-s", "$emu", "shell", "pm", "list", "packages"].execute().text.contains(butlerPackage))
           return;

        final installResult = ["$adb", "-s", "$emu", "install", "$butlerApkPath"].execute().text

        if (!installResult.contains("Success"))
            println "Could not install APK. Install output:\n$installResult"

        else
            println "Installed $butlerApkPath in $emu successfully"

    }
}

}

然而,当我通过终端运行它时,任务结束了。我不知道为什么。我做了一些关于它的研究,有一次我认为传递给ProcessGroovyMethods'执行的命令失败了,因为它是作为一个字符串(execute(String self))传递的,所以我然后使用了execute的数组表示({ {1}})看看这是否有效,但我仍然得到相同的结果,所以我只是要求有经验写这些任务的人给我一些帮助。到目前为止,我正在打印命令的结果,并且没有显示任何错误。它只是在建筑过程中停留数小时。

execute(String[] commandArray)

1 个答案:

答案 0 :(得分:2)

嗯,这是预期的行为。

如果你密切关注你的输出,你会看到

  

模拟器:连接的设备列表

所以关注你的代码:

println "Emulator: $it"

输出我引用的那行

final emu = it.split("\\s")[0]

获取第一个空格分隔的标记List

checks whether the APK is already installed

这甚至都不会编译,但我想你只是忘记了你在问题中添加的评论字符作为解释

if (["$adb", "-s", "$emu", "shell", "pm", "list", "packages"].execute().text.contains(butlerPackage))
       return;

现在执行adb -s List shell pm list
手动执行此操作两次为我打印error: device not found然后退出,因此contains条件为falsereturn未完成。

final installResult = ["$adb", "-s", "$emu", "install", "$butlerApkPath"].execute().text

现在执行adb -s List install butler.apk
这三次手动执行打印出error: device not found,然后打印一次- waiting for device -,然后坐在那里等到你取消它,或者序列号为List的设备变得可用当然永远不会发生因此你的任务会一直持续到你杀了它为止。

在处理设备列表时,您必须跳过标题行,因为这当然不是设备。

除此之外,您当然可以使用Groovy标准方法来执行外部命令。然而,在Gradle中,我宁愿使用Gradle变体。如果你只想执行一件事,那就是Exec类型的任务,如果你想执行多个事情,比如你的情况,那就是Project.exec()Script.exec()方法,所以你会做像

这样的事情
def output
new ByteArrayOutputStream().withStream { baos ->
    exec {
        executable adb
        args "-s", emu, "shell", "pm", "list", "packages"
        standardOutput os
    }.assertNormalExitValue()
    output = baos.toString()
}
if (output.contains(butlerPackage)) {
    return
}

exec {
    executable adb
    args "-s", emu, "install", butlerApkPath
}.assertNormalExitValue()