动态插件

动态插件提供将插件插入正在运行的 Eclipse 实例和从中除去插件的能力。对于可能要卸装的可重用组件,动态插件提供一种容易的方式来帮助您跟踪插件的进出。

在应用程序的生命周期中,动态插件可能不会一直保持,这样的话,确保当该组件离开时清除所有它的一切就非常重要。当在工作台上挂接了侦听器且注册了项时,这些侦听器和项在关闭之后仍保留在工作台中,这些插件必须知道需要清除它们。

在启动时读一遍扩展点的所有实现对于应用程序的生命是足够的这一假定,在应用程序不工作时是错误的。您必须确保挂接了侦听器或未曾执行任何操作,以便侦听到注册表更改。了解工作台中的项不一定是静态的很重要,它们事实上是瞬态的,可以在任何时候离开。如果您要为特定视图编写插件,则首先确保该视图仍在那里。

作为插件开发者,您需要确保允许您可能利用的任何扩展在任何给定的时刻出现或消失。当它们消失时,您应通过清除可能表示这些扩展的任何内部结构来确认它们的消失,并除去它们可能驱动的任何用户界面工件。当它们出现时,您应增加内部结构并可能应创建新的用户界面工件。假定您的应用程序正在读取注册表且具有一个扩展,则您应该为该应用程序创建一条记录并指定其位置。最后,系统将通知您需要进行清除。另外,当新项进入以及创建它们时,侦听器还会进行通知。

org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker 和相关联的接口提供了一个机制,插件开发者可以通过该机制容易地跟踪扩展的进出并管理由这种操作生成的资源。

以下示例假定您在称为窗口小部件的插件中有一个扩展点且您正在使用 IExtensionTracker。在内部,您有一些包括窗口小部件扩展的 WidgetDescriptors 和一个用来管理它们的 WidgetRegistry。



	public class WidgetRegistry implements IExtensionChangeHandler {

	
	
	  public WidgetRegistry() {
		
		IExtensionTracker tracker = PlatformUI.getWorkbench()
	
  	.getExtensionTracker();
IExtensionPoint point = Platform.getExtensionRegistry() .getExtensionPoint("my.plugin.namespace", "widget");
IExtension[] extensions = point.getExtensions();
// initial population
for (int i = 0; i < extensions.length; i++) { addExtension(tracker, extensions[i]);
} tracker
.registerHandler(this, tracker
.createExtensionPointFilter(point)); } public void addExtension(IExtensionTracker tracker, IExtension extension){ WidgetDescriptor descriptor = new WidgetDescriptor(extension); tracker.registerObject(extension, descriptor,
IExtensionTracker.REF_STRONG); addToInternalStructure(descriptor) } private void addToInternalStructure(WidgetDescriptor descriptor) { // registry specific logic } public void removeExtension(IExtension extension, Object[] objects) { for (int i = 0; i < objects.length; i++) { WidgetDescriptor descriptor = (WidgetDescriptor) objects[i];
removeFromInternalStructure(descriptor);
}
} private void removeFromInternalStructure(WidgetDescriptor descriptor) { // registry specific logic }
} public void dispose() { PlatformUI.getWorkbench() .getExtensionTracker().unregisterHandler(this)
} }

在此示例中,平台用户界面在各种级别的工作台中提供 IExtensionTracker 实例。如果您要跟踪在工作台的生命周期内一直存在的对象,则您应使用由 IWorkbench.getExtensionTracker() 提供的跟踪程序。如果您的对象与特定的工作台窗口或页面相关,则您应使用由 IWorkbenchWindow.getExtensionTracker() 或 IWorkbenchPage.getExtensionTracker() 提供的跟踪程序。例如,工作台跟踪工作台级别的视图描述符,但也跟踪工作台页面级别的实际视图实例。您可以通过将 IFilter 实例提供给 IExtensionTracker.registerHandler() 来针对特定扩展点注册您的处理程序。仅当添加或除去与 IFilter 对象匹配的扩展时才会调用您的处理程序。

当扩展进入运行时时,将调用此方法。然后,您的处理程序有机会将新的扩展合并到其相关联的模型中。应通过 IExtensionTracker.registerObject() 针对跟踪程序注册基于对此接口提供的 IExtension 所创建的任何对象。当扩展离开运行时时,将调用此方法。先前针对扩展注册的任何对象将作为自变量传递。然后您的处理程序可以按需要清除和除去对象。注销您的处理程序以便注册表不会泄漏是一个好的习惯。