Flutter带参数论坛帖子缓存问题:无网时无法显示缓存内容
问题解决:无网络时无法加载缓存帖子的修复方案
核心问题定位
你的代码里**forceRefresh: true**是关键问题——这个参数会强制Dio每次都从网络拉取数据,完全忽略本地缓存,导致无网络时直接请求失败,拿不到之前缓存的内容。另外,请求异常时没有处理缓存读取逻辑,直接返回空数组,也会导致列表无数据。
具体修复步骤
1. 修改帖子获取方法getModel
- 移除
forceRefresh: true,让Dio优先使用缓存; - 添加异常捕获,当网络请求失败时,尝试读取缓存数据;
- 兼容缓存响应的状态码(缓存响应状态码通常为304)。
Future<List<ForumCategoryModel>> getModel() async { try { Response response = await dio.get( view_url, queryParameters: { "category": widget.category.toString(), "limit": limit.toString(), }, options: buildCacheOptions( const Duration(days: 7), maxStale: const Duration(days: 10), // 移除forceRefresh,默认优先用缓存,有网时自动更新缓存 ), ); // 缓存响应状态码为304,网络成功为200,统一处理 if (response.statusCode == 200 || response.statusCode == 304) { List<ForumCategoryModel> list = fromJson(response.data); return list; } else { return []; } } catch (e) { // 网络异常时,尝试读取本地缓存 try { // 构建与Dio缓存规则一致的key String cacheKey = "$view_url?category=${widget.category.toString()}&limit=${limit.toString()}"; CacheObject? cacheObject = await DioCacheManager.getInstance().getCache(cacheKey); if (cacheObject != null && cacheObject.data != null) { List<ForumCategoryModel> list = fromJson(cacheObject.data.toString()); return list; } } catch (cacheError) { print("读取帖子缓存失败: $cacheError"); } return []; } }
2. 修改用户信息获取方法getusr
同样处理缓存和异常,确保无网络时能加载缓存的用户信息:
Future getusr(String uid) async { try { Response response = await dio.get( user_info, queryParameters: {"user_id": uid.toString()}, options: buildCacheOptions( const Duration(days: 7), maxStale: const Duration(days: 10), // 移除forceRefresh ), ); if (response.statusCode == 200 || response.statusCode == 304) { return json.decode(response.data); } } catch (e) { // 读取用户信息缓存 try { String cacheKey = "$user_info?user_id=$uid"; CacheObject? cacheObject = await DioCacheManager.getInstance().getCache(cacheKey); if (cacheObject != null && cacheObject.data != null) { return json.decode(cacheObject.data.toString()); } } catch (cacheError) { print("读取用户信息缓存失败: $cacheError"); } } return []; }
3. 优化列表加载逻辑
确保缓存数据获取后能正确更新UI,同时完善加载状态:
getlist() async { setState(() { loading = false; // 开始加载时显示加载中 }); cagetoryList = await getModel(); setState(() { loading = true; // 加载完成(网络/缓存)更新状态 }); }
额外说明
- Dio缓存的key是请求完整URL(含query参数),手动读取时要保证key与请求生成的一致;
- 如果需要主动刷新缓存,可以在下拉刷新时临时设置
forceRefresh: true,平时保持缓存优先; - 测试无网络场景前,需先正常加载一次数据,确保缓存已写入本地。
内容的提问来源于stack exchange,提问作者bybenjo
相关产品推荐
相关产品推荐

