【问题标题】:Gradle task using adb to install apk not being executed使用 adb 安装 apk 的 Gradle 任务未执行
【发布时间】:2017-06-17 04:25:05
【问题描述】:

我正在编写一个 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

【问题讨论】:

    标签: android gradle groovy android-emulator adb


    【解决方案1】:

    嗯,这是预期的行为。

    如果你仔细观察你的输出,你会看到

    模拟器:附加设备列表

    所以按照你的代码:

    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 条件是 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 的设备可用,这当然永远不会发生,因此您的任务挂起直到你杀了它。

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

    除此之外,您当然可以使用 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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 2016-08-25
      • 1970-01-01
      • 2019-10-23
      • 1970-01-01
      • 2017-07-29
      相关资源
      最近更新 更多