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

问题描述:

我有一个RCP应用程序,它使用到内存数据库的连接。有一种情况是,在关闭窗口时,应用程序被终止而没有机会关闭与数据库的连接。为Eclipse RCP应用程序添加Shutdown Hook的正确方法是什么?

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

我尝试下面的代码,我从我IApplication实施者start()方法执行,之前的RCP应用程序实际上是启动:

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

凡清理()关闭与数据库的连接。如果打开任何文档,关闭应询问用户保存。

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

+1

我也有,但如果JVM终止此部分不被调用。例如,由于System.exit() – 2009-05-07 11:50:49

注:本blog entry提示为关机钩以下实现:

关机代码必须在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 
    } 
    } 
} 

它被设置,如你所说,在应用程序:

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