Gradle 使用 adb 安装 apk 的任务未被执行
Gradle task using adb to install apk not being executed
我正在编写 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(String[] commandArray)
) 看看这是否可行,但我仍然得到相同的结果,所以我只是请求有编写这些任务经验的人给我一些帮助。到目前为止,我正在打印命令的结果并且没有显示任何错误。它只是在构建过程中停留了几个小时。
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Users\Joel\Documents\Projects\Forms>gradlew installButlerApk
Picked up _JAVA_OPTIONS: -XX:ParallelGCThreads=2
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon:
https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html.
Incremental java compilation is an incubating feature.
:app:installButlerApk
Verifying test-butler installation in emulators
Emulator: List of devices attached
> Building 0% > :app:installButlerApk
嗯,这是预期的行为。
如果仔细查看输出,您会发现
Emulator: List of devices attached
所以按照你的代码:
println "Emulator: $it"
输出我引用的那行
final emu = it.split("\s")[0]
采用第一个 space 分隔标记,即 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
条件是 false
而 return
没有完成。
final installResult = ["$adb", "-s", "$emu", "install", "$butlerApkPath"].execute().text
现在你执行adb -s List install butler.apk
手动执行这三次打印出 error: device not found
,然后打印一次 - waiting for device -
然后坐在那里等待直到您取消它,或者序列号为 List
的设备可用,这当然永远不会发生因此你的任务挂起,直到你杀死它。
您在浏览设备列表时必须跳过 header 行,因为这当然不是设备。
除此之外,您当然可以使用Groovy标准方式来执行外部命令。然而,在 Gradle 中,我宁愿使用 Gradle 变体。如果你只想执行一件事,那将是 Exec
类型的任务,如果你想像你的情况一样执行多件事,那就是 Project.exec()
or 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()
我正在编写 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(String[] commandArray)
) 看看这是否可行,但我仍然得到相同的结果,所以我只是请求有编写这些任务经验的人给我一些帮助。到目前为止,我正在打印命令的结果并且没有显示任何错误。它只是在构建过程中停留了几个小时。
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Users\Joel\Documents\Projects\Forms>gradlew installButlerApk
Picked up _JAVA_OPTIONS: -XX:ParallelGCThreads=2
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon:
https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html.
Incremental java compilation is an incubating feature.
:app:installButlerApk
Verifying test-butler installation in emulators
Emulator: List of devices attached
> Building 0% > :app:installButlerApk
嗯,这是预期的行为。
如果仔细查看输出,您会发现
Emulator: List of devices attached
所以按照你的代码:
println "Emulator: $it"
输出我引用的那行
final emu = it.split("\s")[0]
采用第一个 space 分隔标记,即 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
条件是 false
而 return
没有完成。
final installResult = ["$adb", "-s", "$emu", "install", "$butlerApkPath"].execute().text
现在你执行adb -s List install butler.apk
手动执行这三次打印出 error: device not found
,然后打印一次 - waiting for device -
然后坐在那里等待直到您取消它,或者序列号为 List
的设备可用,这当然永远不会发生因此你的任务挂起,直到你杀死它。
您在浏览设备列表时必须跳过 header 行,因为这当然不是设备。
除此之外,您当然可以使用Groovy标准方式来执行外部命令。然而,在 Gradle 中,我宁愿使用 Gradle 变体。如果你只想执行一件事,那将是 Exec
类型的任务,如果你想像你的情况一样执行多件事,那就是 Project.exec()
or 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()