我可以在后台线程中运行Service吗?
我想从数据库加载数据,在加载数据期间,我希望进度条指示进度。首先,我创建了任务,在后台线程中运行它,然后根据此任务更新进度条。但是,我发现这个任务不可重复使用,所以下次按下按钮时,它无法正常工作。稍后,我说服务可以多次运行任务,所以我已经将这些任务封装在服务中。
现在效果很好 - 每次按下按钮,表都会重新加载 - 除了进度条没有移动。
如何达到预期效果?
答案 0 :(得分:0)
好的......这是完成的代码:https://mega.nz/#!yUsjgJyZ!DHfuBqsujAHurS-pQ_W5y8BAflOtvxsm48goRPkDsxA
首先,我想告诉你我的目标是什么:
当我运行程序时,我希望进度条处于不确定状态。按下按钮后,我想要进度条来反映服务的进度。完成服务后,我希望完成进度条(100%)。
这是我发现的。看起来服务自动在后台线程上运行它的任务。我已经建了一个沙箱"我正在玩服务和进度条的程序。该程序包括进度条,两个文本字段,上面有两个按钮。第一个按钮可以启动service_countTo100,第二个按钮可以运行service_getActualCount。
现在在fxml文件中我设置进度条以确定默认状态。按下按钮1后,计数开始(显示在text_field1中),进度条根据实际进度发生变化。按下button2后,计数的实际值显示在text_field2中。这里有一些问题。为了演示这些问题,我将向您展示服务的源代码:
// Create the service
public static Service<Integer> serviceTo100 = new Service<Integer>() {
@Override
protected Task<Integer> createTask() {
Task<Integer> taskTo100 = new Task<Integer>() {
@Override protected Integer call() throws Exception {
int iterations;
updateProgress(-1, 100);
for (iterations = 0; iterations < 100; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateMessage("Iteration " + iterations);
updateProgress(iterations, 100);
// Now block the thread for a short time, but be sure
// to check the interrupted exception for cancellation!
try {
Thread.sleep(100);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
}
}
//udpateProgress(100, 100);
return iterations;
}
};
return taskTo100;
}
};
正如您所看到的,有一个简单的循环,从0到100计数,还有一个updateProgress(iterations, 100);
语句可以更新进度。此服务位于Services
级。在FXMLDocumentController.java中,名为runService(Service service)
的方法定义如下:
public void runService(Service service){
service.start();
progressBar.progressProperty().bind(service.progressProperty());
service.setOnSucceeded((event) -> {
service.reset();
progressBar.progressProperty().unbind();
progressBar.setProgress(1);
});
}
initialize
看起来像这样:
@Override
public void initialize(URL url, ResourceBundle rb) {
btn_start1.setOnAction((event) -> {
Service service = Services.serviceTo100;
runService(service);
txt_field1.textProperty().bind(service.messageProperty());
System.out.printf("something\n");
});
.
.
.
}//end of initialize
现在最有趣的事情(至少对我来说,新手)发挥作用。
在服务定义中,您可以注意到注释行//updateProgress(100,100)
。这是我尝试在计数停止时将进度条设置为已完成状态。但是java忽略了这一行。我试图放System.out.print("Something");
但它有效,但updateProgress(100, 100)
没有。计数完成后,进度条设置为fxml文件中定义的默认状态,这是不确定的。
结论:服务类创建在其中定义的任务,在任务完成后,任务不再存在,因此,没有进度与进度条绑定。< / p>
即使任务不再存在,也无法使用setProgress(double double)
方法设置有界进度条的进度。你首先需要解开它。
现在我得到了我需要的东西:
你运行程序,进度条处于不确定状态,等待命中。按下按钮,服务开始计数到100,进度条根据progressProperty服务进行。计数完成后,进度条设置为再次确定状态,等待另一次启动。