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
相关产品推荐
相关产品推荐

