Home > Software engineering >  Flutter stopwatch running slower than expected
Flutter stopwatch running slower than expected

Time:06-10

My stopwatch is running 0.5x slower than actual time (e.g. while the real time is 1 minute, the stopwatch shows ~34 seconds).

Here is the Provider code:

class TimerState extends ChangeNotifier { 
   late String _stringTimer; 
   late Duration _duration; 
   Timer? _timer; 
  
   TimerState() { 
     _stringTimer = '00:00.00'; 
     _duration = const Duration(); 
   } 
  
   String get get => _stringTimer; 
  
   void start() { 
     _timer = Timer.periodic(const Duration(milliseconds: 1), (_) => _addTime()); 
   } 
  
   void _addTime() { 
     _duration = Duration(milliseconds: _duration.inMilliseconds   1); 
     _formattedTimer(); 
   } 
  
   void _formattedTimer() { 
     String twoDigits(int n) => n.toString().padLeft(2, '0'); 
     final milliseconds = twoDigits((_duration.inMilliseconds.remainder(1000) / 10).floor()); 
     final seconds = twoDigits(_duration.inSeconds.remainder(60)); 
     final minutes = twoDigits(_duration.inMinutes.remainder(60)); 
     _stringTimer = '$minutes:$seconds.$milliseconds'; 
     notifyListeners(); 
   } 
 }

CodePudding user response:

Your approach adds the timer interval (1ms) on each timer event. That is a bad approach because it assumes that your timer fires exactly on every millisecond with no room for error. You also will lose time if any timer events are missed (which might happen if you ever do work that takes longer than 1ms). Error will accumulate.

Also note that 1ms is very short. Redrawing your widget every millisecond would be updating it at a rate of 1000 frames per second.

A much better approach would be to record the start time and, on each timer event, compute the difference from DateTime.now() to the start time (e.g. var elapsed = DateTime.now().difference(startTime);). That will prevent error from accumulating. Better yet, use a Stopwatch object which does that for you.

You also should pick a more reasonable timer interval; picking a rate faster than your screen's refresh rate is wasteful.

  • Related