From b5165de7f0efd7b4dddc0a20355a7353372099ad Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 24 Aug 2021 06:57:38 +0200 Subject: [PATCH] PeriodicTaskExecutor: use a Handler instead of Timer. --- .../services/tasks/PeriodicTaskExecutor.java | 55 +++++++------ .../services/tasks/TimerTaskExecutor.java | 79 ------------------- 2 files changed, 29 insertions(+), 105 deletions(-) delete mode 100644 src/main/java/de/dennisguse/opentracks/services/tasks/TimerTaskExecutor.java diff --git a/src/main/java/de/dennisguse/opentracks/services/tasks/PeriodicTaskExecutor.java b/src/main/java/de/dennisguse/opentracks/services/tasks/PeriodicTaskExecutor.java index 528434b3a..eff52d63b 100644 --- a/src/main/java/de/dennisguse/opentracks/services/tasks/PeriodicTaskExecutor.java +++ b/src/main/java/de/dennisguse/opentracks/services/tasks/PeriodicTaskExecutor.java @@ -15,6 +15,7 @@ */ package de.dennisguse.opentracks.services.tasks; +import android.os.Handler; import android.util.Log; import androidx.annotation.NonNull; @@ -51,14 +52,23 @@ public class PeriodicTaskExecutor { private PeriodicTaskFactory.Task periodicTask; - // Time periodic task executor - private TimerTaskExecutor timerTaskExecutor = null; + private Handler handler; private boolean metricUnits; private TrackStatistics trackStatistics; private Distance nextTaskDistance = Distance.of(Double.MAX_VALUE); + private final Runnable timer = new Runnable() { + @Override + public void run() { + if (trackRecordingService != null && periodicTask != null) { + trackRecordingService.run(periodicTask); + handler.postDelayed(this, getNextDuration()); + } + } + }; + public PeriodicTaskExecutor(@NonNull TrackRecordingService trackRecordingService, PeriodicTaskFactory periodicTaskFactory) { this.trackRecordingService = trackRecordingService; this.periodicTaskFactory = periodicTaskFactory; @@ -67,18 +77,15 @@ public class PeriodicTaskExecutor { taskFrequency = TASK_FREQUENCY_OFF; } - /** - * Restores the executor. - */ public void restore() { if (!trackRecordingService.isRecording() || trackRecordingService.isPaused()) { Log.d(TAG, "Not recording or paused."); return; } - if (!isTimeFrequency() && timerTaskExecutor != null) { - timerTaskExecutor.shutdown(); - timerTaskExecutor = null; + if (!isTimeFrequency() && handler != null) { + handler.removeCallbacks(timer); + handler = null; } if (taskFrequency == TASK_FREQUENCY_OFF) { Log.d(TAG, "Task frequency is off."); @@ -89,33 +96,27 @@ public class PeriodicTaskExecutor { periodicTask.start(); if (isTimeFrequency()) { - if (timerTaskExecutor == null) { - timerTaskExecutor = new TimerTaskExecutor(periodicTask, trackRecordingService); + if (handler == null) { + handler = new Handler(); } - timerTaskExecutor.scheduleTask(Duration.ofMinutes(taskFrequency)); + handler.postDelayed(timer, getNextDuration()); } else { // For distance periodic task updateNextTaskDistance(); } } - /** - * Shuts down the executor. - */ public void shutdown() { if (periodicTask != null) { periodicTask.shutdown(); periodicTask = null; } - if (timerTaskExecutor != null) { - timerTaskExecutor.shutdown(); - timerTaskExecutor = null; + if (handler != null) { + handler.removeCallbacks(timer); + handler = null; } } - /** - * Updates the executor. - */ public void update(@NonNull Track.Id trackId, @NonNull TrackStatistics trackStatistics) { if (!isDistanceFrequency() || periodicTask == null) { return; @@ -165,17 +166,19 @@ public class PeriodicTaskExecutor { return announcementInterval.multipliedBy(index + 1); } - /** - * True if time frequency. - */ private boolean isTimeFrequency() { return taskFrequency > 0; } - /** - * True if distance frequency. - */ private boolean isDistanceFrequency() { return taskFrequency < 0; } + + private long getNextDuration() { + if (!isTimeFrequency()) { + throw new RuntimeException("Using distance frequency as time frequency is impossible."); + } + Duration interval = Duration.ofMinutes(taskFrequency); + return interval.toMillis() - (trackRecordingService.getTotalTime().toMillis() % interval.toMillis()); + } } diff --git a/src/main/java/de/dennisguse/opentracks/services/tasks/TimerTaskExecutor.java b/src/main/java/de/dennisguse/opentracks/services/tasks/TimerTaskExecutor.java deleted file mode 100644 index 6fbc1d727..000000000 --- a/src/main/java/de/dennisguse/opentracks/services/tasks/TimerTaskExecutor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package de.dennisguse.opentracks.services.tasks; - -import java.time.Duration; -import java.util.Date; -import java.util.Timer; -import java.util.TimerTask; - -import de.dennisguse.opentracks.services.TrackRecordingService; - -/** - * This class will periodically perform a task. - * - * @author Sandor Dornbush - */ -class TimerTaskExecutor { - - private final PeriodicTaskFactory.Task periodicTask; - private final TrackRecordingService trackRecordingService; - - private TimerTask timerTask; - private Timer timer; - - public TimerTaskExecutor(PeriodicTaskFactory.Task periodicTask, TrackRecordingService trackRecordingService) { - this.periodicTask = periodicTask; - this.trackRecordingService = trackRecordingService; - } - - /** - * Schedules the periodic task. - */ - void scheduleTask(Duration interval) { - if (!trackRecordingService.isRecording() || trackRecordingService.isPaused()) { - return; - } - - shutdown(); - periodicTask.start(); - timerTask = new TimerTask() { - @Override - public void run() { - trackRecordingService.run(periodicTask); - } - }; - timer = new Timer(TimerTaskExecutor.class.getSimpleName()); - - //TODO Simplify: far too complicated for it's purpose - long next = System.currentTimeMillis() + interval.toMillis() - (trackRecordingService.getTotalTime().toMillis() % interval.toMillis()); - timer.scheduleAtFixedRate(timerTask, new Date(next), interval.toMillis()); - } - - void shutdown() { - if (timerTask != null) { - timerTask.cancel(); - timerTask = null; - } - if (timer != null) { - timer.cancel(); - timer.purge(); - timer = null; - } - periodicTask.shutdown(); - } -}