简体   繁体   English

使用adb安装apk的Gradle任务未执行

[英]Gradle task using adb to install apk not being executed

I am writing a gradle task to install an apk unto emulators before espresso tests are run. 我正在编写gradle任务,以在运行espresso测试之前向模拟器安装apk。

This is the task I have so far. 到目前为止,这是我的任务。

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"

    }
}

} }

However when I run it via the terminal the task ends up freezing. 但是,当我通过终端运行它时,任务最终冻结了。 I am not sure why. 我不知道为什么。 I did some research about it and at one point I thought the command that was being passed to ProcessGroovyMethods' execute was failing because it was being passed as a string ( execute(String self) ) so I then used the array representation of execute ( execute(String[] commandArray) ) to see if that would work but I am still ending up with the same result so I am just asking for someone who has experience writing these tasks to give me some assistance. 我对此进行了一些研究,有一次我认为传递给ProcessGroovyMethods的execute的命令失败了,因为它是以字符串形式传递的( execute(String self) ),因此我使用了execute( execute(String[] commandArray)的数组表示形式execute(String[] commandArray) ),看看是否行得通,但我仍然得到相同的结果,所以我只想请有经验的人编写这些任务来给我一些帮助。 So far, I am printing the result of the command and it hasn't shown any errors. 到目前为止,我正在打印命令的结果,它没有显示任何错误。 It's just stuck at the building process for hours. 它只是在构建过程中停留了几个小时。

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

Well, this is expected behavior. 好吧,这是预期的行为。

If you look at your output closely, you see 如果仔细查看输出,您会看到

Emulator: List of devices attached 仿真器:连接的设备列表

So following your code: 因此,遵循您的代码:

println "Emulator: $it"

outputs that line I quoted 输出我引用的那一行

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

takes the first space separated token which is List 接受第一个以空格分隔的令牌,即List

checks whether the APK is already installed

this will not even compile, but I guess you just forgot the comment characters that you added in the question as explanation 甚至不会编译,但是我想您只是忘记了在问题中添加的注释字符作为解释

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

Now you execute adb -s List shell pm list 现在执行adb -s List shell pm list
Executed manually this two times prints error: device not found for me and then exits, so your contains condition is false and the return is not done. 手动执行这两次会显示error: device not found适合我的error: device not found ,然后退出,因此您的contains条件为falsereturn未完成。

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

Now you execute adb -s List install butler.apk 现在执行adb -s List install butler.apk
Executed manually this three times prints out error: device not found , then one time - waiting for device - and then sits there waiting until you cancel it, or a device with serial number List becomes available which of course will never happen and thus your task hangs until you kill it. 手动执行这三遍将打印出error: device not found ,然后一次- waiting for device -然后坐在那里等待直到您取消它,或者序列号为List的设备可用,这当然将永远不会发生,因此您的任务挂起,直到将其杀死。

You have to skip the header line when you work through the list of devices, as this is of course not a device. 在浏览设备列表时,您必须跳过标题行,因为这当然不是设备。

Besides this, you can of course use the Groovy standard ways to execute external commands. 除此之外,您当然可以使用Groovy标准方法来执行外部命令。 Yet while in Gradle, I'd rather use the Gradle variants. 但是在Gradle中,我宁愿使用Gradle变体。 If you only want to execute one thing it would be a task of type Exec , if you want to execute multiple things like in your case, it is the Project.exec() or Script.exec() methods, so you would do something like 如果您只想执行一件事情,那将是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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM