【发布时间】:2013-06-24 18:08:12
【问题描述】:
我在尝试从 Java 中将 android start-server 作为外部进程运行时遇到了各种问题。 Java 由 Gradle 调用。让我向您描述一下在各种情况下到底发生了什么:
环境
- Windows 7 X64
- Java 7
- commons-exec-1.1
- Gradle 1.6
- Android API 17
- IntelliJ IDEA 12.1.4 社区版
假设
adb 守护进程被杀死并在调用adb start-server 时启动。
案例一
这段代码:
DefaultExecutor executor = new org.apache.commons.exec.DefaultExecutor();
executor.execute(org.apache.commons.exec.CommandLine.parse("adb start-server"));
log.info("Checkpoint!");
从应用插件的 Gradle run 任务运行时,将显示启动服务器输出,即:
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
然后它将挂起,即“检查点!”永远不会被记录。手动杀死adb.exe 进程会导致代码继续执行。
问题 1
为什么这个调用会阻塞?从终端运行adb start-server 命令时,几秒钟后控制权返回到终端,那为什么代码中没有发生呢?
案例 2
如果我像这样直接使用 Java 运行时:
Runtime.getRuntime().exec(new String[]{"adb", "start-server"});
log.info("Checkpoint!");
System.exit(0);
如果像以前一样从 Gradle 调用,“检查点!”将被记录。但是,执行将在System.exit(0) 上挂起。手动杀死 adb.exe 将再次使 Gradle 调用完成。
在这种情况下,不会显示adb start-server 的输出。
有趣的是,当我从 IntelliJ IDEA 运行应用程序而不是 Gradle 时,使用模仿 Gradle 的构建设置运行应用程序时,一切正常并且应用程序正常完成。
问题 2
为什么 Gradle 挂在 System.exit(0) 而 IntelliJ 没有?这是否与 Gradle 本身是一个内部调用 Java 的进程以及在 IntelliJ 的情况下,Java 被立即调用而没有任何间接的事实有关?为什么重要?
问题 3
最终,我希望能够从 Gradle 运行它而不会出现任何挂起。 adb start-server 的日志输出将是一个奖励。我将不胜感激任何提示如何做到这一点。
【问题讨论】:
标签: java gradle adb apache-commons-exec