在插件启动期间执行 UI 相关操作的正确方法是什么

What is the right way to perform UI related operations during plugin start

我需要执行 UI 操作,例如 'removing eclipse default menus'、'registering IWindowCloseHandler' 和 'adding IWorkbenchListener' 等

以上所有操作均在插件start()方法

中完成
start(BundleContext context) {
 ....

Display.getDefault().syncExec(new Runnable() {
 @Override
 public void run() {
    //Disable/Remove eclipse default menu items like Edit, Run etc

    //register workbence register
    final IWorkbench workbench = PlatformUI.getWorkbench();
    final IWorkbenchPage activePage =    workbench.getActiveWorkbenchWindow().getActivePage();
    workbench.getActiveWorkbenchWindow().addPerspectiveListener(pHandler);
    workbench.addWorkbenchListener(new IWorkbenchListener(){                    
        @Override
        public boolean preShutdown(IWorkbench workbench, boolean forced) {
        activePage.closeEditors(activePage.getEditorReferences(), true);
                            return true;
        }
    });     
     //register close handler
     ExitHandler.registerExitHandler();
    }
 }); 
}

public class ExitHandler {
  public static void registerExitHandler() {
     WorkbenchWindow activeWorkbenchWindow = (WorkbenchWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    if (activeWorkbenchWindow != null) {
        MWindow window = activeWorkbenchWindow.getModel();
        if (window != null) {
            window.getContext().set(IWindowCloseHandler.class, new IWindowCloseHandler() {

                @Override
                public boolean close(MWindow window) {
                    //Exit logic involves UI;
                }
            });
        }
    }
  }
} 

有时我在 Display.asyncExec()/syncExec():

中提到的许多 classes 都低于异常
 !MESSAGE While loading class "ExitHandler ", thread "Thread[main,6,main]" timed out waiting (5011ms) for thread "Thread[Thread-6,5,main]" to finish starting bundle "bundlename". To avoid deadlock, thread "Thread[main,6,main]" is proceeding but "ExitHandler " may not be fully initialized.

执行这些操作的正确位置是什么?

  1. 在 org.eclipse.ui.IStartup 或
  2. 的 earlyStartUp() 中
  3. 在 org.osgi.framework.BundleListener 的 bundleChanged() 中或在生命周期 class.
  4. 我对以上两个选项存疑!!还有其他合适的选择吗?

观察:当我的品牌插件发生变化时,会出现上述问题,否则加载工作正常

使用IStartup方法,但您需要使用Display.asyncExec来延迟代码的运行,直到workbench启动完成:

public void earlyStartup()
{
  Display.getDefault().asyncExec(new Runnable() {
    @Override
    public void run() {
      // TODO your code here
    }
  });
}

避免这种情况的一种方法是将所有代码放在激活码的最后,这样您就可以快速退出而无需加载额外的内容 类。

最好使用 aysnc 执行,因为捆绑激活线程将 return 立即进入活动状态,否则捆绑激活线程将被阻塞,直到您的服务结束。

Start(BundleContext context) {
 ....
// this is my last call in the start() method
Display.getDefault().syncExec(new Runnable() {
 @Override
 public void run() {
    //UI logic to disable 
    }
  }
} 

我按照以下方法解决了提到的问题:

  1. 菜单 enable/disable 已在我视图的 init() 中完成,它会在我的包启动后加载。
  2. 捆绑包启动后,我的 'BundleListener' 正在注册 'IWindowCloseHandler' 和 'IWorkbenchListener' 等侦听器。

    public class StudioBundleListener implements BundleListener {
     @Override
       public void bundleChanged(BundleEvent event) {
       String symbolicName = event.getBundle().getSymbolicName();
       int type = event.getType();
       if(symbolicName.equals(MYPlugin.PLUGIN_ID) && type == BundleEvent.STARTED) {
         //Register your listeners
       }
      }
    }
    

捆绑包激活代码末尾的 IStartup 和 async() 仍然导致 class 加载问题,如问题部分所述。