在插件启动期间执行 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.
执行这些操作的正确位置是什么?
- 在 org.eclipse.ui.IStartup 或
的 earlyStartUp() 中
- 在 org.osgi.framework.BundleListener 的 bundleChanged() 中或在生命周期 class.
中
- 我对以上两个选项存疑!!还有其他合适的选择吗?
观察:当我的品牌插件发生变化时,会出现上述问题,否则加载工作正常
使用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
}
}
}
我按照以下方法解决了提到的问题:
- 菜单 enable/disable 已在我视图的 init() 中完成,它会在我的包启动后加载。
捆绑包启动后,我的 '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 加载问题,如问题部分所述。
我需要执行 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.
执行这些操作的正确位置是什么?
- 在 org.eclipse.ui.IStartup 或 的 earlyStartUp() 中
- 在 org.osgi.framework.BundleListener 的 bundleChanged() 中或在生命周期 class. 中
- 我对以上两个选项存疑!!还有其他合适的选择吗?
观察:当我的品牌插件发生变化时,会出现上述问题,否则加载工作正常
使用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
}
}
}
我按照以下方法解决了提到的问题:
- 菜单 enable/disable 已在我视图的 init() 中完成,它会在我的包启动后加载。
捆绑包启动后,我的 '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 加载问题,如问题部分所述。