You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何不重启应用读取更新后的本地JSON文件而非旧缓存数据

问题根因
  • rootBundle 仅用于读取应用编译时打包进安装包的静态资源,这类资源运行时无法被修改,不管你往什么位置写同名文件,调用rootBundle.loadString()永远只会返回安装包内固化的初始版本数据,这是不重启应用读不到新内容的核心原因。
  • 你写入文件时使用的File('jsonfile/primary_values.json')是相对路径,没有指向应用专属的可读写沙盒目录,实际写入的文件位置和你后续读取的位置完全不匹配。
  • 写入操作完成后没有主动触发文件重读与UI刷新逻辑,就算文件写入成功,界面也不会自动同步最新值。
修复方案

1. 统一文件读写路径

应用运行时产生的修改必须存储在系统分配的应用专属沙盒目录中,你需要先将初始打包的JSON文件在首次启动时拷贝到沙盒目录,后续所有读写操作都针对沙盒内的这份文件,不再直接操作rootBundle中的静态资源。
首先实现获取沙盒内目标文件的通用方法:

import 'package:path_provider/path_provider.dart';
import 'dart:convert';
import 'dart:io';

Future<File> _getLocalJsonFile() async {
  // 获取应用可读写的专属文档目录
  final appDocDir = await getApplicationDocumentsDirectory();
  return File('${appDocDir.path}/primary_values.json');
}

实现文件初始化逻辑,首次启动时拷贝静态资源到沙盒:

Future<void> _initJsonConfig() async {
  final configFile = await _getLocalJsonFile();
  // 沙盒中不存在配置文件时,从静态资源拷贝初始版本
  if (!await configFile.exists()) {
    final initialContent = await rootBundle.loadString('jsonfile/primary_values.json');
    await configFile.writeAsString(initialContent);
  }
  // 初始化完成后读取最新内容渲染
  await readJson();
}

2. 改造读文件逻辑

将原来从rootBundle读数据的逻辑,改为直接读取沙盒内的配置文件:

Future<void> readJson() async {
  try {
    final configFile = await _getLocalJsonFile();
    final String fileContent = await configFile.readAsString();
    final data = jsonDecode(fileContent);
    final values = PrimaryValueJson.fromJson(data);
    setState(() {
      if (primaryKey == 'Doctor SSN :') {
        widget.primaryIndex = values.doc_ssn;
        widget.primaryValue = 'DC0${widget.primaryIndex}';
        print(widget.primaryValue);
        print('this is readjson');
      }
    });
  } catch (e) {
    print("读取配置失败: $e");
  }
}

替换initState中的初始化调用:

@override
void initState() {
  super.initState();
  print("I am doctor init screen");
  // 替换原来的readJson()调用
  _initJsonConfig();
}

3. 改造写文件逻辑,写完主动刷新

写入时同样操作沙盒文件,写入完成后主动触发重读,确保UI同步最新值:

Future<void> _writeJson() async {
  try {
    final configFile = await _getLocalJsonFile();
    // 读取沙盒中最新的配置内容,不要读rootBundle
    final String fileContent = await configFile.readAsString();
    final data = jsonDecode(fileContent);
    final values = PrimaryValueJson.fromJson(data);
    
    final PrimaryValueJson updatedConfig = PrimaryValueJson(
      doc_ssn: values.doc_ssn + 1,
      phar_id: values.phar_id,
      ssn: values.ssn,
    );
    
    // 写入更新后的配置
    await configFile.writeAsString(json.encode(updatedConfig.toJson()));
    print('this is writejson:${updatedConfig.doc_ssn}');

    // 清空输入框
    nameController.text = '';
    specialityController.text = '';
    experienceController.text = '';
    widget.primaryIndex = updatedConfig.doc_ssn;
    widget.primaryValue = 'DC0${updatedConfig.doc_ssn}';
    
    // 重读文件刷新UI
    await readJson();
  } catch (e) {
    print("写入配置失败: $e");
  }
}

4. 修复异步调用问题

你原来在insertRecord方法中把异步的_writeJson包在setState里没有等待执行完成,会出现时序问题,将对应代码修改为:

// 移除原来包裹_writeJson的setState
await _writeJson();
setState(() {});

注意:如果之前运行过旧版本代码,建议先卸载应用重装,确保旧的错误路径缓存文件被清理,首次启动会自动完成初始配置拷贝。

内容的提问来源于stack exchange,提问作者Samman Shrestha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:51:28