You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter番茄钟App:SQLite动态数据无重复存储问题排查

番茄钟App SQLite重复存储问题修复方案

核心问题分析

  1. 时间跟踪逻辑混乱:_elapsedTime与_startPauseTime的累加时机错误,导致每次暂停/启动时重复计算时长,最终存入数据库的是累计的总时长而非单次暂停的片段时长。
  2. 会话完成存储错误:计时器结束时直接存入预设的完整时长,而非实际累计的专注时间,造成重复存储。

具体修复步骤

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:34:53