Flutter:测试期间的计时器问题

我的其中一个有一个定期计时器StatelessWidget。无需赘述,下面是一段生成计时器的代码片段:

class AnniversaryHomePage extends StatelessWidget {

. . .

void _updateDisplayTime(StoreInheritedWidget inheritedWidget) {

String anniversaryString = inheritedWidget.prefs.getString('anniversaryDate');

inheritedWidget.store.dispatch(DateTime.parse(anniversaryString));

}

/// Widget Methods

@override

Widget build(BuildContext context) {

final inheritedWidget = StoreInheritedWidget.of(context);

new Timer.periodic(this.refreshRate, (Timer timer) => _updateDisplayTime(inheritedWidget));

. . .

}

当我尝试将应用程序的起点插入时flutter test,出现以下错误消息:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════

The following assertion was thrown running a test:

A periodic Timer is still running even after the widget tree was disposed.

'package:flutter_test/src/binding.dart': Failed assertion: line 668 pos 7:

'_fakeAsync.periodicTimerCount == 0'

问题是,我使用Timer.periodic不正确吗?如果没有,我该如何缓解该错误?

回答:

问题是创建计时器会创建必须处置的资源,因此您的小部件实际上是有状态的,而不是无状态的。具体来说,该build方法可以每秒调用60次(如果平台为120fps

,则可以调用更多次)。少就是优化。

您的代码中有一个非常关键的错误-该build方法每次调用都会创建一个新的Timer。而且由于您的计时器永远不会取消,因此您可以将数百个或数千个事件调度到商店。

为了避免出现这种情况,该框架提供了一个State类,并带有initStateand

dispose生命周期。该框架承诺,如果它重建您的小部件,它将不会调用initState多次,并且会始终调用dispose。这样,您就可以一次创建一个计时器,并在随后的调用中重新使用它build

例如,您可以将您的大部分逻辑移至“州”,如下所示。将refreshRate保留在小部件上,您甚至还可以使用didUpdateWidget生命周期取消和更新计时器。

class AnniversaryHomePage extends StatefulWidget {

@override

State createState() => new AnniversaryHomePageState();

}

class AnniversaryHomePageState extends State<AnniversaryHomePage> {

Timer _timer;

@override

void initState() {

_timer = new Timer.periodic(widget.refreshRate,

(Timer timer) => _updateDisplayTime(inheritedWidget));

super.initState();

}

@override

void dispose() {

_timer.cancel();

super.dispose();

}

@override

Widget build(BuildContext context) {

...

}

}

以上是 Flutter:测试期间的计时器问题 的全部内容, 来源链接: utcz.com/qa/422164.html

回到顶部