Flutter/Dart使用rootBundle加载JSON文件仅首次生效无法跟踪变更
解决Flutter中rootBundle读取assets JSON文件无法感知变更的问题
问题原因
Flutter的rootBundle默认会对所有加载过的assets资源做内存缓存,首次调用loadString读取assets/data.json后,文件内容会被缓存,后续重复调用同路径的loadString方法会直接返回缓存内容,不会重新读取源文件,因此无法感知文件修改。
解决方案
步骤1:清除指定assets资源的缓存
每次加载JSON文件前,先调用evict方法清除对应路径的缓存,强制rootBundle重新读取源文件,修改后的加载逻辑如下:
Future<void> jorgeDeJson() async { // 先清除指定资源的缓存 await rootBundle.evict('assets/data.json'); // 原代码中rootBundle.rootBundle为冗余写法,直接调用rootBundle即可 final jsondata = await rootBundle.loadString('assets/data.json'); JsonData userDetails = JsonData.fromJson(jsonDecode(jsondata)); Shulam = userDetails.Shulam; PostUpSale = userDetails.PostUpSale; WaitingForSpecialDelivery = userDetails.WaitingForSpecialDelivery; StuckOrders = userDetails.StuckOrders; OutForSpecialDelivery = userDetails.OutForSpecialDelivery; Name1 = userDetails.Name1; WaitingOrders1 = userDetails.WaitingOrders1; SentOrders1 = userDetails.SentOrders1; Name2 = userDetails.Name2; WaitingOrders2 = userDetails.WaitingOrders2; SentOrders2 = userDetails.SentOrders2; Name3 = userDetails.Name3; WaitingOrders3 = userDetails.WaitingOrders3; SentOrders3 = userDetails.SentOrders3; Name4 = userDetails.Name4; WaitingOrders4 = userDetails.WaitingOrders4; SentOrders4 = userDetails.SentOrders4; TotalSent = SentOrders1 + SentOrders2 + SentOrders3 + SentOrders4; print(TotalSent); print(Shulam); }
步骤2:修正主逻辑的错误用法
runApp方法全局仅需调用1次,放在死循环中重复调用会导致应用重复挂载,属于错误用法。可通过Timer.periodic实现周期性数据刷新,修改后的主逻辑如下:
import 'dart:async'; void main() async { // 全局仅调用一次runApp启动应用 runApp(const MyApp()); // 启动周期性定时器,每5秒刷新一次JSON数据 Timer.periodic(const Duration(seconds: 5), (timer) async { await jorgeDeJson(); // 如需同步更新UI,可在此处通过状态管理/setState通知界面刷新 }); }
补充说明
- 上述方案仅适用于开发调试场景,正式打包发布后assets目录为只读固定资源,不会发生变更,无需做动态读取处理。
- 若生产环境需要动态加载可修改的配置文件,建议将文件存储到应用私有文档目录,直接使用
dart:io的File类读取,不存在缓存限制。 - 若需要实现文件变更的实时监听而非定时轮询,开发阶段可接入文件监听库监听本地assets文件的修改事件,触发自动刷新逻辑。
内容的提问来源于stack exchange,提问作者Amit Yosef
相关产品推荐
相关产品推荐

