Flutter番茄钟App:SQLite动态数据无重复存储问题排查
番茄钟App SQLite重复存储问题修复方案
核心问题分析
- 时间跟踪逻辑混乱:
_elapsedTime与_startPauseTime的累加时机错误,导致每次暂停/启动时重复计算时长,最终存入数据库的是累计的总时长而非单次暂停的片段时长。 - 会话完成存储错误:计时器结束时直接存入预设的完整时长,而非实际累计的专注时间,造成重复存储。
具体修复步骤
1. 修正时间跟踪逻辑
调整startTimer、pauseTimer、saveFocusSession的时间计算逻辑,确保每次暂停只存储当前片段的时长:
修改startTimer方法
启动时计算上次暂停到当前的时长,累加到_elapsedTime后清空暂停标记,避免重复累加:
void startTimer() { isTimerRunning = true; isPlaying = true; if (_startPauseTime != null) { // 计算暂停间隔时长并累加 _elapsedTime += DateTime.now().difference(_startPauseTime!); // 清空暂停标记,防止重复计算 _startPauseTime = null; } notifyListeners(); }
修改pauseTimer方法
暂停时仅记录当前时间,直接调用saveFocusSession存储已累计的时长:
Future<void> pauseTimer() async { isTimerRunning = false; isPlaying = false; // 记录暂停时间,用于下次启动时计算间隔 _startPauseTime = DateTime.now(); if (_elapsedTime.inSeconds > 0) { await saveFocusSession(isCompleted: false); } notifyListeners(); }
修改saveFocusSession方法
仅存储当前已累计的_elapsedTime,不再额外计算暂停间隔,避免重复:
Future<void> saveFocusSession({bool isCompleted = false}) async { final sessionDuration = _elapsedTime; if (sessionDuration.inSeconds > 0) { await addFocusSession(sessionDuration, isCompleted: isCompleted); } // 清空当前累计时长,准备下一段会话 _elapsedTime = Duration.zero; }
修改resetTimer方法
重置时确保彻底清空所有时间跟踪变量:
Future<void> resetTimer() async { if (_elapsedTime.inSeconds > 0) { await saveFocusSession(isCompleted: false); } isTimerRunning = false; isPlaying = false; timerValue = 0.0; _elapsedTime = Duration.zero; _startPauseTime = null; notifyListeners(); }
2. 修正会话完成存储逻辑
计时器结束时,存入实际累计的专注时长而非预设的完整时长:
void _onTimerComplete() { final provider = Provider.of<FocusProvider>(context, listen: false); // 存入实际累计的专注时长 provider.addFocusSession(provider._elapsedTime, isCompleted: true); // 重置计时器状态 provider.resetTimer(); }
额外优化建议
给addFocusSession增加isCompleted参数,区分完整会话和中断会话,方便后续统计:
Future<void> addFocusSession(Duration sessionDuration, {bool isCompleted = true}) async { final dbHelper = DBHelper(); final today = DateTime.now().toIso8601String().split('T').first; await dbHelper.insertFocusSession( today, sessionDuration.inSeconds, isCompleted); totalFocusTime += sessionDuration; updateGoalPercentage(_dailyGoalInSeconds); notifyListeners(); }
内容的提问来源于stack exchange,提问作者Kusal Darshana
相关产品推荐
相关产品推荐

