有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何实现UI无关的后台工作任务

我正在开发一个桌面GUI应用程序。目前我正在使用Swing,但我希望将来能将其移植到JavaFX或Android

目前,我正在努力实现一个“UI不可知”的后台任务类:目标是能够提交应用程序核心包中的后台任务(不依赖于特定的GUI),并在有GUI的情况下观察任务的进度(使用特定于GUI的进度条等)

Swing有SwingWorker<T, V>link),JavaFX有Task<V>link),Android有AsyncTask<Params, Progress, Result>link)。它们都有相同的用途,实际上有相似的API

这个界面为后台任务提供了必要的功能,这在所有提到的工具包中都可以找到

public interface BackgroundTask<Result, PartialResult> {

    /**
     * This is where the background computation belongs. Background thread.
     * <p>
     * Equivalent of {@link javax.swing.SwingWorker#doInBackground()}, {@link javafx.concurrent.Task#call()}
     * and {@link 安卓.os.AsyncTask#doInBackground()}.
     */
    public Result computeResult();

    /**
     * Can be called from {@link #computeResult()} to update GUI with partial
     * results. Background thread.
     * <p>
     * Equivalent of {@link javax.swing.SwingWorker#publish(Object[])}, and
     * {@link 安卓.os.AsyncTask#publishProgress(Progress)} (sort of). The equivalent in
     * JavaFX is not just a simple method.
     */
    public void partialUpdate(PartialResult... partials);

    /**
     * Called to process partial results. UI thread.
     * <p>
     * Equivalent of {@link javax.swing.SwingWorker#process(java.util.List)} and
     * {@link 安卓.os.AsyncTask#onProgressUpdate(Progress)}
     */
    public void onPartialResult(List<PartialResult> partials);
}

我的后台任务将实现这个接口。我需要一些代码来将BackgroundTask的实例转换为Swing中的SwingWorker(JavaFX中的Task和Android中稍后的AsyncTask)

简单的实现如下所示:

public class SwingBackgroundTask<Result, PartialResult> extends SwingWorker<Result, PartialResult> {
    private final BackgroundTask<Result, PartialResult> task;

    public SwingBackgroundTask(BackgroundTask<Result, PartialResult> task) {
        this.task = task;
    }

    @Override
    protected Result doInBackground() throws Exception {
        return task.computeResult();
    }

    @Override
    protected void process(List<PartialResult> chunks) {
        task.onPartialResult(chunks);
    }
}

然而,这是没有用的。显然,我不能从内部后台任务的computeResult()调用SwingWorker的publish(partialResult)。因此,我的用户永远不会看到后台任务有意义的进展。当然,我可以使用不确定的进度条,但我不喜欢它们

我如何克服这个问题并做一个一般的背景任务


共 (1) 个答案

  1. # 1 楼答案

    鉴于您正试图将流程与特定实现分离,您将需要提供某种API,使您能够以某种统一的方式提供反馈

    最简单的方法可能是为BackgroundTask类提供某种观察者/监听器,感兴趣的各方可以注册以获得通知,BackgroundTask可以用来提供反馈

    这将允许BackgroundTask引发关于给定状态更改或其他通知的事件,实现将能够以特定于实现的方式进行处理