IResourceDelta.ADDED
IResourceDelta.REMOVED
IResourceDelta.CHANGED
IresourceDelta.getFlags()
IResourceDelta.CONTENT
IResourceDelta.REPLACED
IResourceDelta.REMOVED
IResourceDelta.MOVED_FROM
IresourceDelta.getMovedFromPath()
IResourceDelta.MOVED_TO
IresourceDelta.getMovedToPath()
IResourceDelta.MARKERS
(IMarkerDelta[] markers = delta.getMarkerDeltas())
Listener的性能
Resource Change Listener的实现应该是轻量级的,并且能够快速执行。资源改变的通知会被经常的发出,如果Listener的性能不高,将会影响整个平台的性能。如果在Listener中有大量的工作需要做,最好将它放到后台线程中执行。
使用IResourceDelta.findMember(IPath)可以快速定位到我们关注的IresourceDelta,而不必按树状结构依次向下通知。
IresourceDelta.accept(IResourceDeltaVistor)来访问我们关心的ResourceDeltaVistor树的分支。
线程安全问题:我们不能控制我们的Listener会在哪一个线程中执行。Workspace操作会出现在任何的线程中,Resource Change Listener也会运行在触发该操作的任何线程中。如果我们想让我们的更新操作出现在一个特定的线程中,我们不得不确保代码被post到那个线程。通常我们要更新用户界面,就先得到UI的Display对象,使用Display.syncExec()或者Display.asyncExec()方法。
如果采用异步方式执行,需要注意ResourceDelta都有一个“expire date”.如果传递一个IresourceDelta到另外一个线程,如果Listener的ResourceChanged()方法已经在另外一个线程中返回,对IresourceDelta的引用将会发生错误。请确保Listener不会一直保存Resource Delta的引用,因为这些Resource Delta的数量是很大的,如果一直保持对其引用,会导致memory leak.
Sample
|
public class DocIndexUpdater implements IResourceChangeListener { private TableViewer table; //assume this gets initialized somewhere private static final IPath DOC_PATH = new Path("MyProject/doc"); public void resourceChanged(IResourceChangeEvent event) { //we are only interested in POST_CHANGE events if (event.getType() != IResourceChangeEvent.POST_CHANGE) return; IResourceDelta rootDelta = event.getDelta(); //get the delta, if any, for the documentation directory IResourceDelta docDelta = rootDelta.findMember(DOC_PATH); if (docDelta == null) return; final ArrayList changed = new ArrayList(); IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta) { //only interested in changed resources (not added or removed) if (delta.getKind() != IResourceDelta.CHANGED) return true; //only interested in content changes if ((delta.getFlags() & IResourceDelta.CONTENT) == 0) return true; IResource resource = delta.getResource(); //only interested in files with the "txt" extension if (resource.getType() == IResource.FILE && "txt".equalsIgnoreCase(resource.getFileExtension())) { changed.add(resource); } return true; } }; try { docDelta.accept(visitor); } catch (CoreException e) { //open error dialog with syncExec or print to plugin log file } //nothing more to do if there were no changed text files if (changed.size() == 0) return; //post this update to the table Display display = table.getControl().getDisplay(); if (!display.isDisposed()) { display.asyncExec(new Runnable() { public void run() { //make sure the table still exists if (table.getControl().isDisposed()) return; table.update(changed.toArray(), null); } }); } } } |






