我是否使用此:
process = Runtime.getRuntime().exec("logcat -d time");
或那:
process = new ProcessBuilder()
.command("logcat", "-d", "time")
.redirectErrorStream(true)
.start();
我得到了相同的结果:它经常在exec()或start()调用中挂起,无论我尝试做什么! 运行它的线程甚至不能被Thread.interrupt()中断!子进程肯定是启动的,如果被杀死,上面的命令就会返回。
这些调用可能会在第一次尝试时失败,所以没有办法阅读他们的输出!我也可以使用一个简单的“su -c kill xxx”命令行,结果相同!
编辑:使用一些调试日志开始调试NDK项目中的java_lang_ProcessManager.cpp文件!所以这就是我到目前为止所发现的,在fork()之后,父进行了这个:
int result;
int count = read(statusIn, &result, sizeof(int)); <- hangs there
close(statusIn);
虽然孩子的过程不应该阻止它:这就是孩子的行为(如果开始的话!):
// Make statusOut automatically close if execvp() succeeds.
fcntl(statusOut, F_SETFD, FD_CLOEXEC); <- make the parent will not block
// Close remaining unwanted open fds.
closeNonStandardFds(statusOut, androidSystemPropertiesFd); <- hangs here sometimes
...
execvp(commands[0], commands);
// If we got here, execvp() failed or the working dir was invalid.
execFailed:
int error = errno;
write(statusOut, &error, sizeof(int));
close(statusOut);
exit(error);
孩子可能因为两个可重复的原因而失败: 1-子代码没有运行,但父母认为它是! 2-儿童街区 closeNonStandardFds(statusOut,androidSystemPropertiesFd);
在任何一种情况下,父级中的read(statusIn ...)都以死锁结束!并且子进程被遗忘(无法访问,pid未知,没有Process对象)!
答案 0 :(得分:6)
此问题已在Jelly Bean (Android 4.1)中修复,但未在ICS (4.0.4)中修复,我想它永远不会在ICS中修复。
答案 1 :(得分:4)
以上解决方案在任何方面都不可靠,在某些设备上造成更多问题!
所以我恢复了标准.exec()并继续挖掘...
查看挂起的子代码,我注意到子进程在尝试关闭从父继承的所有文件描述符时都会挂起(除了在exec()调用中创建的文件描述符除外)!< / p>
所以我在整个应用程序代码中搜索任何BufferedReader / Writer和类似的类,以确保在调用exec()时它们会被关闭!
问题的频率大大降低,实际上在我调用exec()之前删除了最后打开的文件描述符时,再也没有出现过。
NB:确保SU二进制文件是最新的,它实际上也可能导致此问题!
享受您的搜索;)
答案 2 :(得分:3)
Bionic中的错误修复时间是commited个月前,但它仍未包含在Android 4.0.4中。
答案 3 :(得分:0)
我在ICS上遇到同样的问题(似乎在Android&lt; 4上工作正常)。你找到了解决方案吗?
一个简单的解决方法是在具有超时连接的专用线程中调用“exec”方法,以便可以“检测”这种情况(是的,我知道它不是很优雅......)