【问题标题】:How to implement UI agnostic background worker task如何实现 UI 不可知的后台工作任务
【发布时间】:2014-06-11 22:43:50
【问题描述】:

我正在开发一个桌面 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 android.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 android.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 android.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);
    }
}

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

我怎样才能克服这个问题并制作一个通用的后台任务?

【问题讨论】:

  • 您的任务可以提供一个回调/侦听器/观察者接口,核心实现可以注册到该接口,这样您的Task 将能够引发事件,侦听器会拾取并采取行动
  • 您的评论实际上是一个可以接受的答案,谢谢。

标签: java swing oop swingworker


【解决方案1】:

当您试图将流程与特定实现分离时,您将需要提供某种 API,以便您以某种统一的方式提供反馈。

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

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

【讨论】:

    猜你喜欢
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多