Flutter中用Provider实现多态遇ProviderNotFoundException求助
Provider多态实现报错ProviderNotFoundException排查解决
问题根源
你遇到的ProviderNotFoundException核心原因是:Provider框架默认仅注册你指定的泛型类型实例,不会自动关联其抽象父类。你给WidgetProvider1Or2嵌套的ChangeNotifierProvider注册的是Provider1实例,但组件内监听的是AbstactProvider类型,框架找不到对应抽象类型的注册,因此抛出异常。
解决方法
方法1:直接以抽象类作为Provider泛型
如果WidgetProvider1Or2仅依赖抽象类的接口,无需操作具体子类的独有方法,可直接在ChangeNotifierProvider中声明抽象类为泛型类型,返回具体子类实例:
Widget widgetProvider1Or2 = ChangeNotifierProvider<AbstactProvider>( create: (_) => Provider1(), // 可根据业务条件替换为Provider2,实现多态切换 child: WidgetProvider1Or2(), );
这种方式最贴合多态设计思想,后续切换具体实现时,仅需修改create方法返回的实例,WidgetProvider1Or2无需任何改动。
方法2:同时注册抽象类与具体类关联
若需同时通过具体类和抽象类获取实例(比如其他组件需要调用Provider1的独有方法),可使用MultiProvider同时注册两种类型,确保抽象类关联到已创建的具体实例:
Widget widgetProvider1Or2 = MultiProvider( providers: [ // 注册具体类实例 ChangeNotifierProvider<Provider1>(create: (_) => Provider1()), // 将抽象类关联到已注册的具体实例,避免重复创建对象 Provider<AbstactProvider>( create: (context) => Provider.of<Provider1>(context, listen: false), ), ], child: WidgetProvider1Or2(), );
修正后的完整代码示例
以方法1为例,修改_MyHomePageState的build方法:
class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { Widget widgetProvider1 = ChangeNotifierProvider( create: (_) => Provider1(), child: WidgetProvider1(), ); Widget widgetProvider2 = ChangeNotifierProvider( create: (_) => Provider2(), child: WidgetProvider2(), ); // 关键修改:指定泛型为抽象类,返回具体实例 Widget widgetProvider1Or2 = ChangeNotifierProvider<AbstactProvider>( create: (_) => Provider1(), child: WidgetProvider1Or2(), ); return Scaffold( body: Column( children: [widgetProvider1, widgetProvider2, widgetProvider1Or2], ), ); } }
修改后,WidgetProvider1Or2中的context.watch<AbstactProvider>()即可正常获取实例,不再抛出异常。
内容的提问来源于stack exchange,提问作者user2094482
相关产品推荐
相关产品推荐

