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

Flutter中如何在应用关闭时保存时间并恢复计时?

Flutter 实现应用退出保存时间、重启恢复计时功能

1. 引入依赖

首先在 pubspec.yaml 中添加 shared_preferences 依赖:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2 # 请使用最新版本

执行 flutter pub get 完成依赖安装。

2. 核心逻辑实现

监听应用生命周期,保存退出时间

通过 WidgetsBindingObserver 监听应用状态变化,在应用退到后台或即将退出时记录当前时间戳,重启时计算离线时长并恢复计时:

class _TimerPageState extends State<TimerPage> with WidgetsBindingObserver {
  late SharedPreferences _prefs;
  int _totalSeconds = 0;
  Timer? _countTimer;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _initTimer();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _countTimer?.cancel();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // 应用退到后台/即将退出时,保存当前时间并暂停计时
    if (state == AppLifecycleState.paused || state == AppLifecycleState.detached) {
      _saveExitTime();
      _countTimer?.cancel();
    }
    // 应用回到前台时,恢复计时
    if (state == AppLifecycleState.resumed) {
      _startCounting();
    }
  }

  // 初始化:读取保存的时间,计算离线时长并恢复计时
  Future<void> _initTimer() async {
    _prefs = await SharedPreferences.getInstance();
    final int? lastExitTime = _prefs.getInt('last_exit_ms');
    if (lastExitTime != null) {
      final int now = DateTime.now().millisecondsSinceEpoch;
      // 计算离线时长(转换为秒)
      int offlineSeconds = (now - lastExitTime) ~/ 1000;
      setState(() {
        _totalSeconds += offlineSeconds;
      });
      // 清除已读取的时间戳,避免重复计算
      await _prefs.remove('last_exit_ms');
    }
    _startCounting();
  }

  // 保存退出时的时间戳(毫秒级)
  Future<void> _saveExitTime() async {
    await _prefs.setInt('last_exit_ms', DateTime.now().millisecondsSinceEpoch);
  }

  // 启动计时逻辑
  void _startCounting() {
    _countTimer = Timer.periodic(const Duration(seconds: 1), (_) {
      setState(() {
        _totalSeconds++;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('计时恢复演示')),
      body: Center(
        child: Text(
          '累计计时:$_totalSeconds 秒',
          style: const TextStyle(fontSize: 26),
        ),
      ),
    );
  }
}

3. 关键细节说明

  • 生命周期时机:利用 AppLifecycleState.paused/detached 触发保存逻辑,确保应用退后台或被杀死时都能记录时间;resumed 触发恢复逻辑,回到前台立即继续计时。
  • 时间精度:用毫秒级时间戳计算离线时长,比秒级更精准,避免短时间离线出现误差。
  • 资源清理:在 dispose 中移除监听、取消计时器,防止内存泄漏;恢复计时后删除已读取的时间戳,避免下次启动重复累加。
  • 首次启动处理:第一次打开应用时,因无保存的时间戳,直接从零开始计时,不影响正常逻辑。

内容的提问来源于stack exchange,提问作者Sulaiman Fazli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:32:11