You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
  }
}

关键注意事项

  1. 页面侧必须调用控制器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();
  }
}
  1. 异步请求校验顺序:先判断接口返回是否有效,再检查控制器销毁状态,避免无效数据的无意义处理。

内容的提问来源于stack exchange,提问作者rameez khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 05:05:15