如何在Eclipse RCP中完成项目构建后执行Job/WorkspaceJob?
问题根源
你当前的代码逻辑里,WorkspaceJob执行buildProject()后立刻返回OK_STATUS,但如果buildProject()是异步触发构建(比如调用了Eclipse的异步构建接口,或者依赖自动构建机制),Job会提前结束——done回调触发的时候,实际构建还在后台跑,自然doThis()拿不到更新后的文件。
解决办法
核心思路是:必须等构建完全结束后,再执行doThis()。下面给两种可行方案:
方案1:改成同步构建,阻塞到完成
修改构建逻辑,让buildProject()同步执行,直到构建彻底完成再继续:
private void doSomething(final ModelResource selected) throws Exception{ WorkspaceJob doSomethingJob= new WorkspaceJob("doSomething") { @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { // 替换成同步构建方法,确保构建完成后才返回 syncBuildProject(monitor); return Status.OK_STATUS; } }; doSomethingJob.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { Display.getDefault().asyncExec(() -> doThis()); } }); doSomethingJob.schedule(); } // 同步构建的示例实现 private void syncBuildProject(IProgressMonitor monitor) throws CoreException { IProject targetProject = ...; // 获取你要构建的项目实例 // 用同步模式执行增量构建,可根据需求换成BUILD_FULL_BUILD(全量构建) targetProject.build(IProject.BUILD_INC_BUILD, monitor); // 如果是触发全局构建,用下面的代码等待所有构建任务结束: // Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor); }
方案2:异步构建后,等待构建任务结束
如果没法修改buildProject()的异步行为,就在done回调里加个等待逻辑,等所有构建任务跑完再执行doThis():
private void doSomething(final ModelResource selected) throws Exception{ WorkspaceJob doSomethingJob= new WorkspaceJob("doSomething") { @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { buildProject(); // 保留原异步构建逻辑 return Status.OK_STATUS; } }; doSomethingJob.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { // 新建Job专门等待构建完成,避免卡UI线程 Job waitBuildJob = new Job("Wait for build finish") { @Override protected IStatus run(IProgressMonitor monitor) { try { // 等待自动构建家族的所有任务结束,手动构建用FAMILY_MANUAL_BUILD Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor); // 构建完成后切回UI线程执行doThis() Display.getDefault().asyncExec(() -> doThis()); } catch (InterruptedException | CoreException e) { return Status.CANCEL_STATUS; } return Status.OK_STATUS; } }; waitBuildJob.schedule(); } }); doSomethingJob.schedule(); }
注意事项
- 选对Job家族:
ResourcesPlugin.FAMILY_AUTO_BUILD对应自动构建,FAMILY_MANUAL_BUILD对应手动构建,要和你实际触发的构建类型匹配。 - 绝对不能在UI线程里直接等待构建,会导致界面卡死,必须放到后台Job里处理等待逻辑,再切回UI线程执行
doThis()。
内容的提问来源于stack exchange,提问作者iamroobz
相关产品推荐
相关产品推荐

