Я разрабатываю приложение Flutter с несколькими одновременными таймерами. Эти таймеры должны продолжать работать правильно, даже когда пользователь: < /p>
перемещается в сторону и обратно на страницу
закрывает и вновь открывает приложение
и разблокирует экран устройства
Я реализовал решение с использованием sharedpreferences для сохранения состояния и Applifecyclestate для управления переходами, но я сталкиваюсь с проблемой: с каждой блокировкой экрана/ Цикл разблокировки, таймеры теряют несколько миллисекунд и постепенно отстают. Решение для конечных пользователей. < /p>
текущий код < /h2>
Код: Выделить всё
class TimerController {
final String id;
bool _isRunning = false;
int elapsedSeconds = 0;
DateTime _lastStartTime;
Timer timer;
final Function(int elapsedSeconds) onTick;
TimerController({@required this.id, @required this.onTick});
Future loadState() async {
final prefs = await SharedPreferences.getInstance();
final savedRunningState = prefs.getBool('${id}_running') ?? false;
final savedElapsedSeconds = prefs.getInt('${id}_elapsed_seconds') ?? 0;
final savedStartTime = prefs.getString('${id}_start_time');
if (savedRunningState && savedStartTime != null) {
final startTime = DateTime.parse(savedStartTime);
final currentTime = DateTime.now();
final totalElapsedTime = currentTime.difference(startTime).inSeconds;
elapsedSeconds = totalElapsedTime;
_isRunning = true;
startTimer();
} else {
elapsedSeconds = savedElapsedSeconds;
}
onTick(elapsedSeconds);
}
void startTimer() {
timer = Timer.periodic(
Duration(seconds: 1),
(_) {
elapsedSeconds++;
onTick(elapsedSeconds);
_saveState();
},
);
}
}
// In the main page
void _handleScreenLock() {
_lastPauseTime = DateTime.now();
for (var entry in _timerControllers.entries) {
if (entry.value.isRunning) {
_lastTimes[entry.key] = DateTime.now();
entry.value.timer?.cancel();
}
}
}
void _handleScreenUnlock() {
if (_lastPauseTime == null) return;
final now = DateTime.now();
for (var entry in _timerControllers.entries) {
if (entry.value.isRunning && _lastTimes.containsKey(entry.key)) {
final lastTime = _lastTimes[entry.key];
final diff = now.difference(lastTime).inSeconds;
entry.value.timer?.cancel();
entry.value.elapsedSeconds += diff;
if (entry.value.isRunning) {
entry.value.startTimer();
}
_lastTimes.remove(entry.key);
}
}
}
[*] Использование ApplifeCyclestate для обнаружения, когда приложение переходит на фон/передний план
[*] Сохранение состояний таймера с использованием sharedpreferences
[*] Расчет разницы во времени между блокировкой и разблокировкой
Обновление истекаемого времени на основе этой разницы
< /ul>
Вопросы < /h2>
Почему таймеры теряют точность во время циклов блокировки /разблокировки экрана? /li>
Есть ли более точный способ поддерживать истеченное время во время этих переходов? Точность?>
Подробнее здесь: https://stackoverflow.com/questions/794 ... ock-unlock
Мобильная версия