Flutter中ChangeNotifier调用dispose后二次使用报错如何修复
问题原因
- 手动调用
ChangeNotifier的dispose方法属于错误操作:dispose方法应该由持有Notifier的Provider自动调用,手动调用后全局注册的Provider仍会持有已销毁的实例,第二次进入页面时不会重新创建新实例,就会触发已销毁实例不可复用的报错。 - 当前的
GoogleMapsNotifier的dispose方法遗漏了关闭bounds这个StreamController,存在内存泄漏风险。 - 目前的
GoogleMapsNotifier注册层级不合理:如果注册在全局MaterialApp下,它的生命周期和应用一致,无法跟随页面销毁自动释放。
修复步骤
1. 完善Notifier的dispose逻辑
补全所有StreamController的关闭操作:
@override void dispose() { selectedLocation.close(); bounds.close(); // 新增这行,关闭遗漏的流 super.dispose(); }
2. 删除手动调用dispose的代码
修改返回按钮的逻辑,不要手动销毁Notifier:
onTap: () { Navigator.pop(context); },
3. 将Notifier注册为页面级,和页面生命周期绑定
不要把GoogleMapsNotifier注册在全局,改为在跳转到地图页面时,用ChangeNotifierProvider包裹地图页面,让Provider自动跟随页面生命周期管理实例:
// 跳转到地图页面的逻辑 Navigator.push( context, MaterialPageRoute( builder: (context) => ChangeNotifierProvider( create: (context) => GoogleMapsNotifier(), child: const GoogleMapPage(), // 替换为你的地图页面组件名 ), ), );
如果使用命名路由,在onGenerateRoute中对应地图路由的位置做上述包裹即可。
完成以上修改后,每次进入地图页面都会创建全新的GoogleMapsNotifier实例,页面退出时Provider会自动调用dispose方法释放所有流资源,不会出现实例复用的报错。
内容的提问来源于stack exchange,提问作者TonyWyomy
相关产品推荐
相关产品推荐

