Flutter - 未处理的异常:在 dispose() 后调用了 setState() AND _StreamBuilderBaseState

11 浏览
0 Comments

Flutter - 未处理的异常:在 dispose() 后调用了 setState() AND _StreamBuilderBaseState

当改变设备方向时,我遇到以下错误:

E/flutter (31741): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: setState() called after dispose(): _StreamBuilderBaseState, AsyncSnapshot>>#afadb(lifecycle state: defunct, not mounted)

E/flutter (31741): 如果您在不再出现在widget树中的widget的State对象上调用setState()(例如,其父widget不再在其构建中包含该widget),则会发生此错误。当代码从计时器或动画回调中调用setState()时,可能会发生此错误。

E/flutter (31741): 首选解决方案是在dispose()回调中取消计时器或停止监听动画。另一种解决方案是在调用setState()之前检查此对象的“mounted”属性,以确保对象仍然在树中。

E/flutter (31741): 如果因为其他对象保留对该State对象的引用而在调用setState(),则此错误可能表示内存泄漏。为避免内存泄漏,在dispose()期间考虑断开与该对象的引用。

E/flutter (31741): #0 State.setState. (package:flutter/src/widgets/framework.dart:1204:9)

E/flutter (31741): #1 State.setState (package:flutter/src/widgets/framework.dart:1239:6)

E/flutter (31741): #2 _StreamBuilderBaseState._subscribe. (package:flutter/src/widgets/async.dart:140:9)

E/flutter (31741): #3 _StartWithValueStream.listen. (package:moor/src/utils/start_with_value_transformer.dart:49:17)

E/flutter (31741): #4 _rootRun (dart:async/zone.dart:1182:47)

E/flutter (31741): #5 _CustomZone.run (dart:async/zone.dart:1093:19)

E/flutter (31741): #6 _CustomZone.runGuarded (dart:async/zone.dart:997:7)

E/flutter (31741): #7 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23)

E/flutter (31741): #8 _rootRun (dart:async/zone.dart:1190:13)

E/flutter (31741): #9 _CustomZone.run (dart:async/zone.dart:1093:19)

E/flutter (31741): #10 _CustomZone.runGuarded (dart:async/zone.dart:997:7)

E/flutter (31741): #11 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1037:23)

E/flutter (31741): #12 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)

E/flutter (31741): #13 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)

E/flutter (31741):

现在,我知道关于if (mounted) setState修复,但问题是我在我的应用程序中没有使用setState,因为我使用bloclibrary

此外,根据错误信息,我可以看到StreamBuilder>,这是以下代码片段引发问题的唯一线索:

...

@override

Widget build(BuildContext context) {

return StreamBuilder>(

stream: RepositoryProvider.of(context)

.scheduledActivitiesDao

.watchActivitiesByPlant(widget.plantId),

builder: (context, snapshot) {

if (snapshot.hasError) print('>>>> DB error - ${snapshot.error}');

if (!snapshot.hasData) return ProgressIndicatorWidget();

return Text('items = ${snapshot.data.length}');

},

);

}

...

对于上面的代码,有两个注意事项:

  1. 上面我发布的build函数所在的Widget是StatefulWidget,但即使我将其重构为StatelessWidget,仍然会出现相同的错误
  2. 这个问题只会在我从横向切换到纵向模式时出现。
0
0 Comments

Flutter - Unhandled Exception: setState() called after dispose() AND _StreamBuilderBaseState

最近在使用Flutter开发过程中,遇到了一个问题:Unhandled Exception: setState() called after dispose() AND _StreamBuilderBaseState。经过排查,发现该问题的出现原因是每次build方法被调用时,都会创建一个新的Stream对象。

为了解决这个问题,我进行了代码重构,具体步骤如下:

1. 添加一个Stream对象_stream,用于存储数据流。

Stream> _stream;

2. 在didChangeDependencies方法中设置_stream的值。

void didChangeDependencies() {

super.didChangeDependencies();

_stream = RepositoryProvider.of(context)

.scheduledActivitiesDao

.watchActivitiesByPlant(widget.plantId);

}

3. 将原先的代码替换为使用_stream的方式。

stream: _stream,

通过以上步骤的重构,成功解决了Unhandled Exception: setState() called after dispose() AND _StreamBuilderBaseState的问题。现在在调用setState方法时不会引发错误,同时也能正常使用StreamBuilder进行数据流的构建。

希望以上的解决方法对于其他遇到类似问题的开发者有所帮助。如果您在Flutter开发中遇到了类似的错误,可以尝试按照上述步骤进行代码重构,看看是否能够解决问题。祝您的Flutter开发之路顺利!

0