flutter 定期定时器有时会延迟,不工作,故意抖动

ryevplcw  于 2022-11-17  发布在  Flutter
关注(0)|答案(2)|浏览(587)

Flutter中的计时器表现与预期不同。
如果我以毫秒为单位为每个周期调用一个特定的函数,
它可能滞后于周期。
即使我只测试了计时器,而没有其他代码,它也做到了。
当我用其他代码测试时,延迟的程度变得严重。
如果延迟保持在~99毫秒是可以的,但是如果我在我的应用程序中使用计时器,它会跳到100~1000毫秒。
我测试了定时器(dart:异步),节拍器(颤抖库),定时器(dart:异步)在隔离。
一个有趣现象是,当我把这些定时器设置为相同周期并启动时,
这些计时器在相似的时刻延迟相似的持续时间。例如,当我在我的应用程序代码中测试这些计时器时,这三个计时器同时延迟1000毫秒。(内存使用量大吗?)
下面是测试代码。我在Galaxy Tab S4上进行测试。(真实的设备)
如何使用以毫秒为单位的计时器?

//code for isolate
DateTime lastIsolate;
DateTime currentIsolate;
int isolateCounter = 0;

void timerTest(SendPort sendPort){
  print("Start Timer");

  lastIsolate = DateTime.now();
  Timer timer = Timer.periodic(Duration(milliseconds: 20), checkTimerPeriod);
  ReceivePort receivePort = ReceivePort();

  sendPort.send(receivePort.sendPort);
  receivePort.listen((message){
    if(message is bool){
      timer.cancel();
    }
  });
}

void checkTimerPeriod(Timer timer){
  currentIsolate = DateTime.now();
  Duration diff = currentIsolate.difference(lastIsolate);
  if(diff.inMilliseconds > 30){
    isolateCounter++;
    print("${DateTime.now()}] Isolate :: ${diff.inMilliseconds}, $isolateCounter times");
  }
  lastIsolate = currentIsolate;
}

void main() {
  ensureInitializedForSharedPreference();
  SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight]) ;
  runApp(MyApp());
}

void ensureInitializedForSharedPreference(){
  WidgetsFlutterBinding.ensureInitialized() ;
}

class MyApp extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    return MyAppState();
  }
}

class MyAppState extends State<MyApp>{
  Isolate isolate;
  ReceivePort _receivePort = ReceivePort();
  DateTime _lastTimer;
  DateTime _currentTimer;
  DateTime _lastMetronome;
  DateTime _currentMetronome;
  Timer timer;
  StreamSubscription<DateTime> metronome;
  int timerCounter;
  int metronomeCounter;

  @override
  void initState() {
    super.initState();
    timerCounter = 0;
    metronomeCounter = 0;
    startTimers();
    spawnIsolate();
  }

  void startTimers(){
    _lastTimer = DateTime.now();
    _lastMetronome = DateTime.now();
    timer = Timer.periodic(Duration(milliseconds: 20), timerCheck) ;
    metronome = Metronome.epoch(aMillisecond * 20).listen((event) {
      metronomeCheck();
    });
  }

  void timerCheck(Timer timer){
    _currentTimer = DateTime.now();
    Duration diff = _currentTimer.difference(_lastTimer);
    if(diff.inMilliseconds > 30){
      timerCounter++;
      print("${DateTime.now()}] Timer :: ${diff.inMilliseconds}, $timerCounter times");
    }
    _lastTimer = _currentTimer;
  }

  void metronomeCheck(){
    _currentMetronome = DateTime.now();
    Duration diff = _currentMetronome.difference(_lastMetronome);
    if(diff.inMilliseconds > 30){
      metronomeCounter++;
      print("${DateTime.now()}] Metronome :: ${diff.inMilliseconds}, $metronomeCounter times");
    }
    _lastMetronome = _currentMetronome;
  }

  void spawnIsolate() async {
    isolate = await Isolate.spawn(timerTest, _receivePort.sendPort);
  }

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      title: 'My App',
      debugShowCheckedModeBanner: false,
      home: TimerTestPage()
//      home: MyHomePage(),
    );
  }
}

class TimerTestPage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return TimerTestPageState();
  }
}

class TimerTestPageState extends State<TimerTestPage>{

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

打印结果:

I/flutter (11728): 2020-11-18 18:00:54.002557] Metronome :: 99, 2 times
I/flutter (11728): 2020-11-18 18:00:54.002805] Timer :: 91, 2 times
I/flutter (11728): 2020-11-18 18:00:54.137470] Timer :: 45, 3 times
I/flutter (11728): 2020-11-18 18:00:54.137680] Metronome :: 35, 3 times
I/flutter (11728): 2020-11-18 18:00:54.456208] Metronome :: 34, 4 times
I/flutter (11728): 2020-11-18 18:00:55.063127] Metronome :: 38, 5 times
I/flutter (11728): 2020-11-18 18:00:55.108351] Timer :: 37, 4 times
I/flutter (11728): 2020-11-18 18:00:55.209915] Metronome :: 67, 6 times
I/flutter (11728): 2020-11-18 18:00:55.210140] Timer :: 56, 5 times
I/flutter (11728): 2020-11-18 18:00:58.800702] Metronome :: 49, 7 times
I/flutter (11728): 2020-11-18 18:00:58.801505] Timer :: 50, 6 times
I/flutter (11728): 2020-11-18 18:00:58.845783] Isolate :: 49, 2 times
I/flutter (11728): 2020-11-18 18:00:59.838194] Timer :: 40, 7 times
I/flutter (11728): 2020-11-18 18:00:59.838950] Metronome :: 35, 8 times
I/flutter (11728): 2020-11-18 18:01:00.835309] Metronome :: 52, 9 times
I/flutter (11728): 2020-11-18 18:01:00.837709] Timer :: 44, 8 times
I/flutter (11728): 2020-11-18 18:01:01.779771] Metronome :: 37, 10 times
I/flutter (11728): 2020-11-18 18:01:02.802442] Metronome :: 59, 11 times
I/flutter (11728): 2020-11-18 18:01:02.803132] Timer :: 51, 9 times
I/flutter (11728): 2020-11-18 18:01:02.827479] Isolate :: 31, 3 times
I/flutter (11728): 2020-11-18 18:01:03.800940] Metronome :: 52, 12 times
I/flutter (11728): 2020-11-18 18:01:03.801845] Timer :: 49, 10 times
I/flutter (11728): 2020-11-18 18:01:03.835860] Isolate :: 39, 4 times
I/flutter (11728): 2020-11-18 18:01:04.860201] Timer :: 66, 11 times
I/flutter (11728): 2020-11-18 18:01:04.860752] Metronome :: 57, 13 times
I/flutter (11728): 2020-11-18 18:01:04.871719] Isolate :: 35, 5 times
I/flutter (11728): 2020-11-18 18:01:05.797080] Metronome :: 54, 14 times
I/flutter (11728): 2020-11-18 18:01:05.798653] Timer :: 46, 12 times
I/flutter (11728): 2020-11-18 18:01:06.798412] Metronome :: 51, 15 times
I/flutter (11728): 2020-11-18 18:01:06.799347] Timer :: 47, 13 times
I/flutter (11728): 2020-11-18 18:01:07.802850] Metronome :: 52, 16 times
I/flutter (11728): 2020-11-18 18:01:07.803528] Timer :: 52, 14 times
I/flutter (11728): 2020-11-18 18:01:07.832428] Isolate :: 36, 6 times
I/flutter (11728): 2020-11-18 18:01:08.798311] Metronome :: 56, 17 times
I/flutter (11728): 2020-11-18 18:01:08.802467] Timer :: 50, 15 times
I/flutter (11728): 2020-11-18 18:01:09.810389] Timer :: 58, 16 times
I/flutter (11728): 2020-11-18 18:01:09.811026] Metronome :: 48, 18 times
I/flutter (11728): 2020-11-18 18:01:09.835066] Isolate :: 38, 7 times
I/flutter (11728): 2020-11-18 18:01:10.810530] Metronome :: 65, 19 times
I/flutter (11728): 2020-11-18 18:01:10.812136] Timer :: 60, 17 times
I/flutter (11728): 2020-11-18 18:01:10.830197] Isolate :: 34, 8 times
I/flutter (11728): 2020-11-18 18:01:11.810372] Timer :: 48, 18 times
I/flutter (11728): 2020-11-18 18:01:11.810956] Metronome :: 48, 20 times
I/flutter (11728): 2020-11-18 18:01:11.826718] Isolate :: 31, 9 times
I/flutter (11728): 2020-11-18 18:01:12.802337] Timer :: 50, 19 times
I/flutter (11728): 2020-11-18 18:01:12.810522] Metronome :: 47, 21 times
I/flutter (11728): 2020-11-18 18:01:12.841223] Isolate :: 44, 10 times
I/flutter (11728): 2020-11-18 18:01:13.631729] Timer :: 36, 20 times
I/flutter (11728): 2020-11-18 18:01:13.801782] Metronome :: 58, 22 times
I/flutter (11728): 2020-11-18 18:01:13.802542] Timer :: 50, 21 times
I/flutter (11728): 2020-11-18 18:01:13.835463] Isolate :: 39, 11 times
I/flutter (11728): 2020-11-18 18:01:14.789602] Timer :: 35, 22 times
I/flutter (11728): 2020-11-18 18:01:15.754015] Metronome :: 31, 23 times
I/flutter (11728): 2020-11-18 18:01:15.811248] Isolate :: 35, 12 times
I/flutter (11728): 2020-11-18 18:01:16.753175] Timer :: 36, 23 times
I/flutter (11728): 2020-11-18 18:01:16.787876] Metronome :: 33, 24 times
I/flutter (11728): 2020-11-18 18:01:16.791421] Timer :: 34, 24 times
I/flutter (11728): 2020-11-18 18:01:17.839036] Metronome :: 55, 25 times
I/flutter (11728): 2020-11-18 18:01:17.842928] Timer :: 51, 25 times
I/flutter (11728): 2020-11-18 18:01:17.871998] Isolate :: 35, 13 times
I/flutter (11728): 2020-11-18 18:01:18.804048] Timer :: 52, 26 times
I/flutter (11728): 2020-11-18 18:01:18.804922] Metronome :: 41, 26 times
I/flutter (11728): 2020-11-18 18:01:18.836156] Isolate :: 39, 14 times
I/flutter (11728): 2020-11-18 18:01:19.796440] Metronome :: 45, 27 times
I/flutter (11728): 2020-11-18 18:01:19.797077] Timer :: 45, 27 times
I/flutter (11728): 2020-11-18 18:01:20.755218] Metronome :: 31, 28 times
I/flutter (11728): 2020-11-18 18:01:20.794793] Timer :: 37, 28 times
I/flutter (11728): 2020-11-18 18:01:20.798211] Metronome :: 36, 29 times
I/flutter (11728): 2020-11-18 18:01:21.803089] Metronome :: 59, 30 times
I/flutter (11728): 2020-11-18 18:01:21.803601] Timer :: 51, 29 times
I/flutter (11728): 2020-11-18 18:01:22.283024] Timer :: 32, 30 times
I/flutter (11728): 2020-11-18 18:01:22.755033] Metronome :: 31, 31 times
I/flutter (11728): 2020-11-18 18:01:22.790614] Metronome :: 35, 32 times
I/flutter (11728): 2020-11-18 18:01:22.794945] Timer :: 38, 31 times
I/flutter (11728): 2020-11-18 18:01:22.815671] Isolate :: 39, 15 times
I/flutter (11728): 2020-11-18 18:01:23.163503] Timer :: 31, 32 times
I/flutter (11728): 2020-11-18 18:01:23.795069] Metronome :: 51, 33 times
I/flutter (11728): 2020-11-18 18:01:23.795837] Timer :: 43, 33 times
I/flutter (11728): 2020-11-18 18:01:23.841426] Isolate :: 43, 16 times
I/flutter (11728): 2020-11-18 18:01:24.795185] Metronome :: 49, 34 times
I/flutter (11728): 2020-11-18 18:01:24.795927] Timer :: 44, 34 times
I/flutter (11728): 2020-11-18 18:01:25.804665] Timer :: 52, 35 times
I/flutter (11728): 2020-11-18 18:01:25.805359] Metronome :: 41, 35 times
I/flutter (11728): 2020-11-18 18:01:25.831298] Isolate :: 35, 17 times
I/flutter (11728): 2020-11-18 18:01:26.806900] Metronome :: 39, 36 times
I/flutter (11728): 2020-11-18 18:01:26.807681] Timer :: 35, 36 times
I/flutter (11728): 2020-11-18 18:01:26.832718] Isolate :: 36, 18 times
at0kjp5o

at0kjp5o1#

Timer.periodic文档中:
确切的计时取决于底层计时器实现。在持续时间 * n时间内进行的回调不会超过n次,但两次连续回调之间的时间可以比持续时间更短或更长。
dart中的Timer并不像你期望的那样精确。

r8uurelv

r8uurelv2#

来自@Lee3的答案是绝对正确的。Timer.periodic按照设计工作。但是如果你需要Timer.periodic工作更可靠,当涉及到一致的tickrate检查这个小包:reliable_periodic_timer
它使用了Timer.periodic,但它会根据当前毫秒数来检查是否已经是正确的触发时间。
它的用法是这样的:

ReliableIntervalTimer(
    interval: Duration(milliseconds: 100),
    callback: (elapsedMilliseconds) => print('elapsedMilliseconds: $elapsedMilliseconds');,
);

相关问题