Использую ли я это:
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", тот же результат!
EDIT: начата отладка файла java_lang_ProcessManager.cpp в проекте NDK с некоторыми журналами отладки! Итак, вот что я нашел до сих пор, после 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);
В любом случае чтение (statusIn...) в родительском завершается в тупике! и дочерний процесс остается мертвым (и к нему нельзя получить доступ, pid неизвестно, нет объекта процесса)!