Flutter已登录后重启应用触发The getter 'auth' was called on null错误
错误原因
核心原因是Provider.of(context)返回了null,你后续调用.auth时触发了空指针异常,只有重启应用后触发的原因如下:
- 你的
Provider没有包裹在应用根节点,而是嵌套在登录流程的子路由下:未登录、登录过程中页面都在Provider的子树范围内,所以可以正常获取实例;重启应用后因为持久化登录态直接跳转到登录后的首页,此时页面上下文不在Provider的子树范围内,无法获取到Provider实例就返回null。 - 你定义的
Provider.of方法没有做非空校验,dependOnInheritedWidgetOfExactType在找不到对应InheritedWidget时会直接返回null,没有提前暴露问题。
修复方案
1. 调整Provider的挂载位置到应用根节点
修改main.dart中的代码,在初始化AuthService后将Provider包裹整个MaterialApp,保证所有路由的上下文都能访问到Provider:
void main() { // 提前初始化AuthService final AuthService authService = AuthService(); runApp( Provider( auth: authService, child: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( // 你的应用路由、主题等原有配置 ); } }
2. 给Provider的of方法增加非空校验
修改provider.dart中的of静态方法,增加断言和非空处理,开发阶段就能提前发现Provider缺失的问题:
static Provider of(BuildContext context) { final Provider? provider = context.dependOnInheritedWidgetOfExactType<Provider>(); assert(provider != null, '当前上下文无法找到Provider实例,请确认Provider已包裹在根节点'); return provider!; }
3. 优化FutureBuilder的使用(可选)
不要直接在future参数中调用Provider.of(context).auth.getCurrentUser(),避免组件重绘时重复触发请求,改为在State的initState中提前缓存future:
late Future userFuture; @override void initState() { super.initState(); userFuture = Provider.of(context).auth.getCurrentUser(); } // 后续FutureBuilder直接使用缓存的future即可 FutureBuilder( future: userFuture, builder: (context, snapshot) { // 保持原有业务逻辑不变 } )
4. 排查ThreadItem组件逻辑
报错指向lib\threadMain.dart:37的ThreadItem组件,确认该组件中调用Provider的地方是否和profile.dart存在同样的问题,按上述方案统一修改即可。
内容的提问来源于stack exchange,提问作者Soo
相关产品推荐
相关产品推荐

