我们的 Android 应用生成一个 logcat shell 进程,然后读取其结果进行处理。 但是,当应用程序停止时(例如在开发期间重新编译后重新启动时),logcat 进程将继续运行。这是此行为的示例:
processes = new ArrayList<Process>();
try {
processes.add(Runtime.getRuntime().exec("logcat -v time"));
processes.add(Runtime.getRuntime().exec("logcat -v time"));
processes.add(Runtime.getRuntime().exec("logcat -v time"));
processes.add(Runtime.getRuntime().exec("logcat -v time"));
} catch (IOException e) {
// oh no!
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
for (Process p : processes) {
p.destroy();
}
};
});
将其添加到测试应用的 onCreate() 方法中,启动它,然后使用设置管理器强制停止它。子进程将继续运行,现在 parent-id 为 1。
在How to kill logcat process initiated by Android application?有人建议使用 ProcessBuilder,但这不是解决方案,进程也会继续运行。
在Stop child process when parent process stops建议使用关闭 Hook - 如上所示,它也不起作用。
谢谢!
最佳答案
您可以做的是生成另一个脚本,其唯一目的是监视您的 Java 程序。每当它死亡时,也杀死它的所有 child 。
一个脆弱的例子:
int pid = android.os.Process.myPid();
String script = "while [ -d /proc/" + pid + " ];do sleep 1;done; killall logcat";
Process p = Runtime.getRuntime().exec("/system/bin/sh", "-c", script);
这假设您的进程不以 root 身份运行,因此只会杀死它自己的 logcat 进程。在您的关闭函数中,您应该首先终止其他进程 (logcat
),然后运行 p.destroy();
来停止这个 killer 级脚本。
可以通过删除 killall
的使用来改进上面的脚本。相反,使用反射获取 logcat
进程的进程 ID(this answer 指向 http://www.golesny.de/p/code/javagetpid)并将它们传递给 kill
。
关于Android:子进程(logcat)在父进程(app)死后继续运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16173387/