我创建了一个Java应用程序,其中main方法(程序的开始)启动一个Process对象和MainWindow类的一个对象,该对象创建一个JFrame。
public static void main(String[] args) throws Exception {
File file = new File("./access/run.bat");
ProcessBuilder process_builder = new ProcessBuilder("cmd", "/c", file.getName());
process_builder.directory(file.getParentFile());
Process process = process_builder.start();
MainWindow window = new MainWindow(process);
}
当窗口关闭时,我想终止(kill)已经用 process.destroy()实例化的进程。以下是MainWindow类的一些代码:
public MainWindow(final Process process) throws TransformerException, ParserConfigurationException, Exception{
JFrame mainWindowFrame = new JFrame();
*****some code here*****
mainWindowFrame.addWindowListener(new WindowListener() {
public void windowClosed(WindowEvent arg0) {
process.destroy();
System.exit(0);
}
*****some code here*****
}
}
当窗口关闭时,不幸的是,这个过程没有被杀死......有人可以给我一个解释吗?一个可能的解决方案?感谢!!!
答案 0 :(得分:1)
根据文档here,只有在窗口被释放时才会调用windowClosed。为此,您可以在窗口上调用dispose或设置默认的关闭操作:在代码中,在创建JFrame之后,添加以下内容:
mainWindowFrame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
在查看您的代码后,我建议您采用不同的方式: 在你的听众中,你正在摧毁这个过程,然后退出。因此,你可以设置deafualt关闭操作退出然后执行中断的过程 实现 windowClosing 方法:将MainWindow的代码修改为以下内容:
public MainWindow(final Process process) throws TransformerException, ParserConfigurationException, Exception{
JFrame mainWindowFrame = new JFrame();
mainWindowFrame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
*****some code here*****
mainWindowFrame.addWindowListener(new WindowListener() {
public void windowClosing(WindowEvent arg0) {
process.destroy();
}
*****some code here*****
}
}
答案 1 :(得分:0)
Process
班的Javadoc说:
The subprocess is not killed when there are no more references
to the Process object, but rather the subprocess
continues executing asynchronously.
There is no requirement that a process represented
by a Process object execute asynchronously or concurrently
with respect to the Java process that owns the Process object.
在互联网上搜索后,从Java 1.3开始,它似乎是Java平台中的issue。我发现这个blog entry解释了Java中Process
的许多问题。
问题是process
在杀死应用程序后成为孤儿。在您的代码中,您将从GUI中删除Process
,因为GUI(MainWindow类)具有自己的线程,而不是Process
父级。这是父母/孩子的问题。
有两种方法可以解决这个问题:
由于主线程是父进程,因此主线程必须调用destroy
方法。因此,您必须保留对process
对象的引用。
第二种方法是在启动MainWindow
时创建流程。在MainWindow类的参数中,您可以传递进程的参数。因此,当调用windowClosed
方法时,如果MainWindow关闭,Process
将被销毁,因为后者是MainWindow的子节点。