未处理的异常:产品在处置后被使用

  • 本文关键字:异常 未处理 flutter dart
  • 更新时间 :
  • 英文 :


我正在使用MultiProvider,但出现此错误:

Unhandled Exception: A Products was used after being disposed. Once you have called dispose() on a Products, it can no longer be used.

这是我的主.dart文件。这种结构有什么问题?

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Auth(),
),
ChangeNotifierProxyProvider<Auth, Products>(
update: (ctx, auth, previousProducts) => Products(
auth.token,
auth.userId,
previousProducts == null ? [] : previousProducts.items,
),
),
ChangeNotifierProvider.value(
value: Cart(),
),
ChangeNotifierProxyProvider<Auth, Orders>(
update: (ctx, auth, previousOrders) => Orders(
auth.token,
auth.userId,
previousOrders == null ? [] : previousOrders.orders,
),
),
],
child: Consumer<Auth>(
builder: (ctx, auth, _) => MaterialApp(
title: 'MyShop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
home: auth.isAuth
? ProductOverviewScreen()
: FutureBuilder(
future: auth.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? SplashScreen()
: AuthScreen(),
),
routes: {
ProductDetailScreen.routeName: (ctx) => ProductDetailScreen(),
CartScreen.routeName: (ctx) => CartScreen(),
OrdersScreen.routeName: (ctx) => OrdersScreen(),
UserProductsScreen.routeName: (ctx) => UserProductsScreen(),
EditProductsScreen.routeName: (ctx) => EditProductsScreen(),
},
),
),
);
}
}

use yourProvider.value 而不是创建

itemBuilder: (ctx, index) => ChangeNotifierProvider.value(
value: products[index],
child: ProductItem(),
),
itemCount: products.length,
);

我也遇到了同样的错误,我通过以下方式解决了它:

ChangeNotifierProvider<"Provider name">.value(value:<PassedValue>);

似乎 ChangeNotifierProvider创建了一个提供程序的实例,当它的工作完成时,dispose(( 方法被调用,因此,该实例被 ChangeNotifierProvider.value 清除,事实并非如此,我们能够重用之前创建的实例。

以下是官方文档: https://pub.dev/packages/provider

这就是您可以修复它的方法

GridView.builder(
padding: const EdgeInsets.all(10),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10),
itemBuilder: ((context, i) => ChangeNotifierProvider.value( //   <--

value: productsItems[i],
child: ProductItem(),
)),
itemCount: productsItems.length,
);
}

在产品概述屏幕中为产品提供程序添加延迟;

@override
void initState() {
Future.delayed(Duration(seconds: 1)).then((_) {
Provider.of<Products>(context, listen: false).fetchAndSetProducts();
});
super.initState();
}

例如,这样做:

return MaterialPageRoute(
builder: (_) => ChangeNotifierProvider<EntryPermitViewModel>.value(
value: EntryPermitViewModel(),
child: const EntryPermitScreen(),
),
);

我认为您必须将产品提供程序添加到提供程序:[] 上面的代理提供程序作为身份验证提供程序的定义,如下所示:

providers: [
ChangeNotifierProvider<Auth>.value(
value: Auth(),
ChangeNotifierProvider<Products>.value(
value: Products(),
ChangeNotifierProxyProvider<Auth, Products>(
update: (ctx, auth, previousProducts) => Products(
auth.token,
auth.userId,
previousProducts == null ? [] : previousProducts.items,
),
),
ChangeNotifierProvider<Cart>.value(
value: Cart(),
),
ChangeNotifierProxyProvider<Auth, Orders>(
update: (ctx, auth, previousOrders) => Orders(
auth.token,
auth.userId,
previousOrders == null ? [] : previousOrders.orders,
),
),
],

使用

Navigator.of(context).pushNamed('/');

在你的抽屉里,你打电话给logout. 这将解决这个问题 谢谢。。

最新更新