1. 资源改变资源改变可以分为两种情况:
1. 有UI参与的
2. 没有UI参与的
首先介绍没有UI参与的。没有UI参与的时候可以使用以下三种方式:
1.老的IWorkspace的run方法
使用方式如下:
final IFile[] files = getSelectedFiles();
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
for (int i = 0; i < files.length; i++) {
files[i].setContents(
modifyContents(files[i].getContents()), false,
true, monitor);
}
}
}, null);
这种方式的问题就在于:
它将锁定我们的任务直到其他的任务完成了并且将继续锁定后续的修改资源的任务直到它完成了
如果monitor传入一个null,那么在我们和任务被阴止时,工作台也提供一个对话框,并且不显示进度!
以上造成的问题之一就是程序响应变得很慢了!
2.新的IWorkspace的run方法
使用方式如下:
final IFile[] files = getSelectedFiles();
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
for (int i = 0; i < files.length; i++) {
files[i].setContents(
modifyContents(files[i].getContents()), false,
true, monitor);
}
}
}, modifyRule(files), IResource.NONE, monitor);
这是上面的run方法的改进版。在3.0以后新加的。修改了旧的方式的缺点!应该总是使用新的而不是旧的!
3.使用IProgressService
使用第二种方式显然是挺好的,不过我们可以提供给用户更多的交互,例如取消,显示进度等等。这可以通过
IProgressService实现,通常的使用如下:
其中service的run方法的前两个参数分别表示:fork和cancelable。
final IFile[] files = getSelectedFiles();
WorkspaceModifyOperation op = new WorkspaceModifyOperation(
modifyRule(files)) {
protected void execute(IProgressMonitor monitor)
throws CoreException {
for (int i = 0; i < files.length; i++) {
files[i].setContents(
modifyContents(files[i].getContents()), false,
true, monitor);
}
};
};
// Use the progess service to execute the runnable
IProgressService service = PlatformUI.getWorkbench()
.getProgressService();
try {
service.run(true, true, op);
} catch (InvocationTargetException e) { // Operation was canceled
} catch (InterruptedException e) { // Handle the wrapped exception
}
2. 以上资源改变的第一第二种方式在没有UI参与的情况下可以工作的很好!但是如果有UI的参与,那么可能就会导致问题的发生了!当有UI参与的时候,可以使用第三种方式的另一个方法:runInUI。当然了,我们还可以在一个job中使用syncExec()或asyncExec()方法!所以这个问题是可以解决的!还有一个问题:在代码运行期间用户还是什么都不能做,因为progress service会首先显示一个busy的光标,然后如果在一段时间内工作还没有完成,则会显示出一个进度对话框!对于这个问题:这里还有一种选择就是使用:WorkspaceJob。一般使用示例如下:
final IFile[] files = getSelectedFiles();
WorkspaceJob job = new WorkspaceJob("Modify some files") {
public IStatus runInWorkspace(IProgressMonitor monitor)
throws CoreException {
for (int i = 0; i < files.length; i++) {
files[i].setContents(
modifyContents(files[i].getContents()), false,
true, monitor);
}
return Status.OK_STATUS;
}
};
job.setRule(modifyRule(files));
job.schedule();
它类似于IWorkspace,不过它的好处就是可以在后台运行!可以允许用户执行其他任务。不好之处就是:与给一个对话框相比,提供回显给用户是更复杂的!