Flutter页面关闭时终止ChangeNotifier的notifyListeners避免崩溃
解决Flutter页面切换后notifyListeners()触发崩溃的问题
问题背景
使用混入ChangeNotifier的MatchListController时,页面加载会发起异步接口请求getMatchList()。若请求未完成时切换页面,接口返回后调用notifyListeners()会导致应用崩溃,需实现页面关闭时终止notifyListeners()的执行。
核心解决方案:控制器销毁状态标记
通过添加状态标记跟踪控制器是否已被销毁,在调用notifyListeners()前校验状态,同时重写dispose方法更新标记。
修改后的完整代码
class MatchListController with ChangeNotifier { List<MatchData> liveMatches = []; // 标记控制器是否已被销毁 bool _isDisposed = false; MatchListController() { getMatchList(); } Future<void> getMatchList() async { debugPrint('match list api called'); final response = await ApiService().matchList(); // 仅在控制器未销毁且接口返回有效数据时执行后续逻辑 if (response != null && !_isDisposed) { final databody = json.decode(response); // 先更新数据再通知监听者(避免空数据触发刷新) liveMatches = List<MatchData>.from( databody.map((item) => MatchData.fromJson(item)) ); notifyListeners(); } } @override void dispose() { _isDisposed = true; super.dispose(); } }
关键注意事项
- 页面侧必须调用控制器dispose:在使用该控制器的StatefulWidget的
dispose方法中,手动调用控制器的dispose(),确保标记被正确更新:
class MatchListPageState extends State<MatchListPage> { late final MatchListController _controller; @override void initState() { super.initState(); _controller = MatchListController(); } @override void dispose() { _controller.dispose(); super.dispose(); } }
- 异步请求校验顺序:先判断接口返回是否有效,再检查控制器销毁状态,避免无效数据的无意义处理。
内容的提问来源于stack exchange,提问作者rameez khan
相关产品推荐
相关产品推荐

