当我在Runnable中使用我的逻辑时,它工作得很好,除了我无法与UI线程交互。因此,我试图将所有内容放在一个扩展Task的类中,并且它可以工作除了任务只执行一次。没有错误,我从任务成功的方法中获得了成功的消息。
我也尝试在调用方法中使任务返回布尔值为true,但这没有帮助。
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception{
SyncTask syncTask = new SyncTask();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(syncTask, 0, 10, TimeUnit.SECONDS);
Label syncEngineLabel = centralController.getScheduleTabMessageLabel();
syncEngineLabel.textProperty().bind(syncTask.messageProperty());
}
class SyncTask extends Task<Void>{
private Schedule schedule = null;
public SyncTask() {}
@Override
protected Void call() throws Exception {
System.out.println("we are in the task...");
if (getScheduleFromApi()){
updateMessage("New Schedule Retrieved...");
}
return null;
}
@Override protected void succeeded() {
super.succeeded();
System.out.println("succeeded");
}
@Override protected void cancelled() {
super.cancelled();
System.out.println("cancelled");
}
@Override protected void failed() {
super.failed();
System.out.println("failed");
}
private Boolean getScheduleFromApi(){
Gson gson = new GsonBuilder().serializeNulls().create();
ApiGet api = new ApiGet("schedule/get-schedule-by-room", parameters);
api.sendRequest();
if (api.isSuccess()){
schedule = gson.fromJson(api.response(), Schedule.class);
if (schedule.getStatus().equals("200")){
return true;
}
else{
updateMessage(schedule.getMsg());
return false;
}
}
else {
updateMessage("Failed to process API call to ASI Server.");
return false;
}
}
}
}
请注意,此代码实际存在于控制器内部,但我将其放在Main中以尝试提供自包含代码。
谢谢!
答案 0 :(得分:2)
ScheduledExecutorService
只会将您提供的任务视为Runnable
,并尝试在每次运行时重复使用相同的任务实例,这在documentation中明确禁止。< / p>
改为使用ScheduledService
:
@Override
public void start(Stage primaryStage) throws Exception{
ScheduledService<Void> scheduledService = new ScheduledService<Void>() {
@Override
protected Task<Void> createTask() {
return new SyncTask();
}
};
scheduledService.setPeriod(Duration.seconds(10));
scheduledService.start();
Label syncEngineLabel = centralController.getScheduleTabMessageLabel();
scheduledService.stateProperty().addListener((obs, oldState, newState) -> {
if (newState == Worker.State.RUNNING) {
syncEngineLabel.setText("Sync in progress");
} else if (newState == Worker.State.FAILED) {
syncEngineLabel.setText("Sync error");
} else {
syncEngineLabel.setText("Sync complete");
}
});
}