从Java中执行adb命令

5
我希望能够从我的Java程序推送一个文件到Android模拟器。现在,我可以使用ProcessBuilder启动模拟器,并捕获logcat消息。但是,每当我尝试在进程构建器中使用adb push命令时,该进程会挂起,没有输出产生。
代码如下:
try {
    ProcessBuilder proc = new ProcessBuilder("D://android-sdk//platform-tools//adb.exe",
                                             "push D:\\final.xml /mnt/sdcard/final.xml");
    Process p = proc.start();
    BufferedReader br2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ( (line = br2.readLine()) != null)
        System.out.println(line);
} catch (Exception e) {
    System.err.println("Error");
}

编辑: 找到了可能的解决方案。我使用了Process.waitFor()方法,但没有存储其返回的退出代码。现在我这样做:

int exitVal = p.waitFor();

一切都运作得很好。

感谢@Marc Van Daele的贡献。根据我的经验,ProcessBuilder可以两种方式工作,即您可以使用由空格或逗号分隔的参数。 :)


说实话,我认为存储waitFor的返回值解决不了这个问题。我更倾向于认为有时候你读取InputStream中的数据足够快(然后它可以正常工作),有时候你读取不够快,就会遇到“挂起”问题。 - Marc Van Daele
是的,我编辑后感觉有点奇怪。但是现在已经有一段时间没有遇到同样的问题了。谢谢你们的帮助 :) - user1471910
1个回答

5
这不应该是分开的参数,例如:
ProcessBuilder proc = new ProcessBuilder("D://android-sdk//platform-tools//adb.exe", "push",  "D:\\final.xml", "/mnt/sdcard/final.xml");

你正在读取p.getInputStream()吗?我认为你应该同时读取OutputStream和ErrorStream。也许,设置proc.redirectErrorStream(true)并且只读取OutputStream是个好主意。你可能会遇到“因为某些本地平台仅为标准输入和输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取其输出流可能会导致子进程阻塞,甚至死锁。”如http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html所述。 - Marc Van Daele
请忽略我上面有关输入输出流的错误评论。但是,我的其他评论仍然有效。 - Marc Van Daele
我实际进行了一些实验,这个答案似乎是正确的。 - Andrey Ermakov
太棒了!非常好的答案..节省了很多时间..非常感谢! - Danger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接