【问题标题】:Android: Child process (logcat) keeps running after parent process (app) diedAndroid:父进程(app)死亡后子进程(logcat)继续运行
【发布时间】:2013-04-16 21:44:42
【问题描述】:

我们的 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() 方法中,启动它,然后使用设置管理器强制停止它。子进程将继续运行,现在其父 ID 为 1。

在How to kill logcat process initiated by Android application? 中,有人建议使用 ProcessBuilder,但这不是一个解决方案,该进程也将继续运行。

在Stop child process when parent process stops 中建议使用关闭挂钩 - 如上所示,这也不起作用。

谢谢!

【问题讨论】:

  • 您是否尝试在 p.destroy() 之后调用 p.waitFor()?前一个调用等待子进程终止并获得返回状态,然后再继续销毁下一个。
  • @Vikdor 谢谢,但不,不起作用。事实上,在关闭钩子中添加一个日志调用表明当应用程序(强制)停止时它根本不会被调用。
  • 我猜new Thread() 中processes 的副本是空的。您是从for 循环还是从循环外登录的?能否将进程标记为 volatile,以便线程不会缓存副本,然后进行检查?
  • 我在for循环之前登录过,关闭钩子的run()永远不会被调用。

标签: android process logcat


【解决方案1】:

您可以做的是生成另一个脚本,其唯一目的是监视您的 Java 程序。每当它死去时,也要杀死它所有的孩子。

一个脆弱的例子:

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(); 来停止这个杀手脚本。

可以通过删除killall 来改进上面的脚本。相反,使用反射(this answer 指向http://www.golesny.de/p/code/javagetpid)获取logcat 进程的进程ID,并将它们传递给kill。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多