Eclipse resource change notification mechanism

xiaoxiao2021-03-06  70

Eclipse resource change notification mechanism

See the original text:

Http://www.eclipse.org/articles/article-resource-deltas/resource-deltas.html

Resource Change Listener

Interface: IResourceChangelistener

IWorkspace workspace = ResourcesPlugin.getWorkspace (); IResourceChangeListener listener = new IResourceChangeListener () {public void resourceChanged (IResourceChangeEvent event) {System.out.println ( "Something changed!");}}; Workspace.addResourceChangeListener (listener);

// ... Some Time Later One ... Workspace.RemoveresourceChangeListener (Listener);

During the notification of resource changes, Workspace will locate to avoid more notifications.

Resource API

The Resource API will broadcast the resource change event in the event of CREANG, COPYING, MOVING, and DELETI operation.

Resource operations will nest, such as ifile.move operations trigger an instance.create action to create a new file, then trigger an instance.delete action to delete old files. So a ifile.move operation is nested an instance.create action and an instance manual operation, but the above operation will only notify it.

Batching changes

When there is a batch of resource changing events, it is necessary to use Batching's way to improve performance. This ensures that only one resource change event is broadcast, not multiple.

IWorkspace workspace = ResourcesPlugin.getWorkspace (); final IProject project = workspace.getRoot () getProject ( "My Project");. IWorkspaceRunnable operation = new IWorkspaceRunnable () {public void run (IProgressMonitor monitor) throws CoreException {int fileCount = 10; Project.create (NULL); Project.open (NULL); for (int i = 0; i

Eclipse 3.0 no longer guarantees that iWorkSpacerunnable It prevents other notifications during execution. The reason for this is to ensure that the UI can be able to correspond to user events during the notification.

A new class WorkspaceJob is introduced in Eclipse 3.0, allowing a large number of Workspace resource changing operations to a JOB execution in the background.

A more powerful feature When resources are changed outside Workspace, ResourceChangeListener will be notified, such as changes to file system files. Since most operating systems do not have this mechanism, the resource change will notify all listener.iResourceChangeEvent after IResource.Refreshlocal operations.

l Event Type

PRE_CHANGE, POST_CHANGE, PRE_BUILD, POST_BUILD, PRE_CLOSE, POST_CLOSE, PRE_DELETE, POST_DELETE

l IresourceDelta

IResourceDelta.getkind ()

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's performance

The implementation of Resource Change Listener should be lightweight and can be executed quickly. The notice of resource changes will be sent frequently, and if the Listener is not high, it will affect the performance of the entire platform. If there is a lot of work in Listener, it is best to put it in the background thread.

Using IResourceDelta.Findmember (iPath) can quickly locate the IResourceDelta we are concerned, without having to be notified by the tree structure.

IResourceDelta.Accept (IResourceDeltavistor) to access the branch of the ResourceDeltavistor tree we care.

Thread security issues: We can't control which threads will be executed in our Listener. The Workspace action will appear in any thread, and the Resource Change Listener is also running in any thread that triggered the operation. If we want our update operation to appear in a specific thread, we have to ensure that the code is sent to that thread. Usually we want to update the user interface, first get the DISPLAY object of the UI, use the Display.Syncexec () or Display.Asyncexec () method.

If you do use asynchronous mode, you need to pay attention to ResourceDelta. If you pass an IResourceDelta to another thread, if the Listener's ResourceChanged () method is returned in another thread, the reference to IResourceDelta will have an error. Make sure that Listener will not always save Resource Delta reference, because the number of these Resource Delta is very large, if you have kept reference to it, it will cause 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 intended in files with the "txt" extension if (resource.gettype () == IResource.file && "txt" .Equalsignorecase ()) {change.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 Doi Thele 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 Table Still EXISTS IF (Table.getControl ..disposed ()) return; table.update (Changed.toArray (), NULL);}});

转载请注明原文地址:https://www.9cbs.com/read-87682.html

New Post(0)