为Eclipse RCP应用程序添加Shutdown Hook的正确方法是什么?

我有一个RCP应用程序,它使用与内存数据库的连接。 有一种情况是,当关闭窗口时,应用程序将被终止而不会让它有机会关闭与数据库的连接。

我研究了一下,似乎添加Shutdown钩子是检测此事件并在Java应用程序中进行清理的最佳方法。 但是,如果您有一个RCP应用程序,可能需要打开多个编辑器,那么处理此问题的正确方法是什么?

注意:此博客条目建议关闭挂钩的以下实现:

关闭代码必须在UI线程中运行,如果通过其他方式关闭工作台,则不应运行关闭代码。 所有脏编辑器都会自动保存。 这样可以避免在计算机关闭时提示可能在家中睡觉的用户。 最后,工作台已关闭。

(所以不完全是你的场景,但实现仍然很有趣,因为它显示了如何在UI线程中运行它)

private class ShutdownHook extends Thread { @Override public void run() { try { final IWorkbench workbench = PlatformUI.getWorkbench(); final Display display = PlatformUI.getWorkbench() .getDisplay(); if (workbench != null && !workbench.isClosing()) { display.syncExec(new Runnable() { public void run() { IWorkbenchWindow [] workbenchWindows = workbench.getWorkbenchWindows(); for(int i = 0;i < workbenchWindows.length;i++) { IWorkbenchWindow workbenchWindow = workbenchWindows[i]; if (workbenchWindow == null) { // SIGTERM shutdown code must access // workbench using UI thread!! } else { IWorkbenchPage[] pages = workbenchWindow .getPages(); for (int j = 0; j < pages.length; j++) { IEditorPart[] dirtyEditors = pages[j] .getDirtyEditors(); for (int k = 0; k < dirtyEditors.length; k++) { dirtyEditors[k] .doSave(new NullProgressMonitor()); } } } } } }); display.syncExec(new Runnable() { public void run() { workbench.close(); } }); } } catch (IllegalStateException e) { // ignore } } } 

如你所说,它在IApplication中设置:

 public class IPEApplication implements IApplication { public Object start(IApplicationContext context) throws Exception { final Display display = PlatformUI.createDisplay(); Runtime.getRuntime().addShutdownHook(new ShutdownHook()); } // start workbench... } } 

您应该覆盖扩展WorkbenachAdvisor的类的preShutdown方法。 返回false以停止关闭进程,或返回true以继续。

我尝试了以下代码,我在实际启动RCP应用程序之前从IApplication implementsor start()方法执行:

 Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { if (PlatformUI.isWorkbenchRunning()) { PlatformUI.getWorkbench().close(); } logger.info("Shutdown request received"); cleanup(); } }); 

cleanup()关闭与数据库的连接。 如果有任何文档打开,关闭应该要求用户保存。