Запустить службу в фоновом потоке - PullRequest
0 голосов
/ 16 мая 2018

Могу ли я запустить службу в фоновом потоке?

Я хочу загрузить данные из базы данных, и во время загрузки данных я хочу, чтобы индикатор выполнения отображал прогресс. Сначала я создал задачу, запустил ее в фоновом потоке, а затем обновил индикатор выполнения в соответствии с этой задачей. Тем не менее, я обнаружил, что это задание нельзя использовать повторно, поэтому в следующий раз, когда я нажал кнопку, это не сработало. Позже я обнаружил, что Сервис может запускать Задачи несколько раз, поэтому я инкапсулировал эти задачи внутри Сервиса.

Теперь все работает отлично - каждый раз, когда я нажимаю кнопку, таблица перезагружается - за исключением того, что индикатор выполнения не движется.

Как мне достичь желаемого результата?

1 Ответ

0 голосов
/ 17 мая 2018

Хорошо ... Вот полный код: https://mega.nz/#!yUsjgJyZ!DHfuBqsujAHurS-pQ_W5y8BAflOtvxsm48goRPkDsxA

Сначала я хочу рассказать вам, какова моя цель:

Когда я запускаю программу, я хочу, чтобы индикатор выполнениябыть в неопределенном состоянии.После нажатия на кнопку, я хочу, чтобы индикатор выполнения отражал прогресс службы.После завершения службы я хочу, чтобы индикатор выполнения был завершен (100%).

Вот что я нашел.Похоже, сервис автоматически запускает свою задачу в фоновом потоке.Я построил программу «песочницы», где я играл со службами и индикатором выполнения.Программа состояла из индикатора выполнения, двух текстовых полей с двумя кнопками над ними.Первая кнопка может запустить service_countTo100, а вторая кнопка может запустить service_getActualCount.

Теперь в файле fxml я установил индикатор выполнения в неопределенное состояние по умолчанию.После нажатия кнопки 1 начался отсчет (отображается в text_field1), и индикатор выполнения изменился в соответствии с фактическим прогрессом.После нажатия кнопки 2 фактическое значение счетчика отображается в поле 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).Это была моя попытка установить индикатор выполнения в завершенное состояние, когда счет остановился.Но ява проигнорировала эту строчку.Я пытался поставить System.out.print("Something");, и это сработало, но updateProgress(100, 100) не сработало.Когда подсчет завершился, индикатор выполнения был установлен в состояние по умолчанию, определенное в файле fxml, которое было неопределенным.

Вывод: Класс обслуживания создает задание, определенное внутри него, и после его завершения задание больше не существует, поэтому нет прогресса, связанного с индикатором выполнения.

Несмотря на то, что задача больше не существует, вы не можете установить ход выполнения индикатора выполнения с помощью метода setProgress(double double).Сначала нужно отсоединить его.

Теперь я получил то, что мне нужно:

Вы запускаете программу, индикатор выполнения находится в неопределенном состоянии, ожидая удара.Вы нажимаете кнопку, сервис начинает считать до 100, а индикатор выполнения прогрессирует в соответствии с ProProperty службы.Когда подсчет завершен, индикатор выполнения снова устанавливается в неопределенное состояние, ожидая другого запуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...