遭遇ChangeNotifierProxyProvider已释放异常,401 API重试失败
解决ChangeNotifierProxyProvider已释放后仍被使用的API重试问题
问题根源分析
你遇到的核心问题是重试API时触发ChangeNotifierProxyProvider was used after being disposed异常,尽管能成功刷新AccessToken,但重试调用依然失败。问题出在ChangeNotifierProxyProvider的配置逻辑:当前update方法每次都新建ApiCalls实例,导致旧实例被销毁后,重试逻辑仍在引用它,进而引发释放后使用的错误。
解决方案
1. 修复ChangeNotifierProxyProvider的update逻辑
不要每次更新都新建ApiCalls实例,而是复用原有实例并更新token:
ChangeNotifierProxyProvider<Auth, ApiCalls>( create: (_) => ApiCalls(null), update: (context, auth, previous) { // 复用已有实例,仅更新token previous?.updateToken(auth.token); return previous!; }, )
同时在ApiCalls类中添加更新token的方法:
class ApiCalls extends ChangeNotifier { String? _token; ApiCalls(this._token); void updateToken(String? newToken) { _token = newToken; // 若需触发UI更新,可调用notifyListeners(); } // 你的API调用方法,使用_token做授权校验 }
2. 确保重试时使用最新token
在onRetry回调中,等待token刷新完成后,重新构建请求并替换授权头:
final client = RetryClient( http.Client(), retries: 1, when: (response) => response.statusCode == 401, onRetry: (req, res, retryCount) async { print('retry started'); if (retryCount == 0 && res?.statusCode == 401) { // 等待token刷新完成 await Provider.of<Auth>(context, listen: false).restoreAccessToken(); // 获取最新token final newToken = Provider.of<Auth>(context, listen: false).token; // 复制原请求并替换Authorization头 return req.copyWith( headers: { ...req.headers, 'Authorization': 'Bearer $newToken', }, ); } return req; }, );
3. 额外注意事项
- 确保
Auth类的restoreAccessToken方法是异步实现,保证token刷新完成后再执行重试。 - 检查
ApiCalls实例的生命周期,避免在重试过程中被意外销毁。
内容的提问来源于stack exchange,提问作者Santosh Kumar
相关产品推荐
相关产品推荐

