Flutter使用SharedPreferences存储变量重启后归零问题咨询
问题原因
你的代码无法读取到保存值的核心问题非常明确:loadData方法中成功解析出存储的Data模型对象后,没有将解析得到的计数值赋值给State层的counter、counter2状态变量。
你现在的逻辑只是把读到的值打印到了控制台,页面渲染时始终用的是两个变量初始化的0值,自然重启后看不到之前保存的计数。
错误代码定位
问题出在loadData的异步逻辑中,你把setState提前包裹了读值操作,但解析完成后没有做赋值:
loadData() async { SharedPreferences prefs = await SharedPreferences.getInstance(); setState(() { String? json = prefs.getString('UserData'); print('loaded json: $json'); if (json == null) { print('NO DATA (null)'); } else { Map<String, dynamic> map = jsonDecode(json); print('map $map'); final data = Data.fromJson(map); print('Data ${data.counter}, ${data.counter2}'); // 缺失核心赋值逻辑 } }); }
顺带提一句,这里把SharedPreferences实例获取、JSON解析这类异步/计算操作放在setState里本身也不合理,setState里只应该放更新状态变量的同步操作。
修正后的完整loadData方法
loadData() async { // 先完成异步读取、解析操作 SharedPreferences prefs = await SharedPreferences.getInstance(); String? json = prefs.getString('UserData'); print('loaded json: $json'); if (json == null) { print('NO DATA (null)'); return; } Map<String, dynamic> map = jsonDecode(json); print('map $map'); final data = Data.fromJson(map); print('Data ${data.counter}, ${data.counter2}'); // 仅在更新状态变量时调用setState,触发页面重绘 setState(() { counter = data.counter; counter2 = data.counter2; }); }
替换掉原来的loadData方法后,重启应用就能正确读到之前保存的计数值了。
可选优化点
- 可以把存储用的key抽成常量,避免手写字符串拼写错误导致读写key不匹配,比如
const String kUserDataKey = 'UserData',存、读、清除操作都复用这个常量。 - 现在点击悬浮按钮时
increment()是同步更新状态,saveData()是异步存值,逻辑上不会有问题,但如果后续有更复杂的状态更新逻辑,建议等状态更新完成后再执行持久化操作,避免存到旧值。
内容的提问来源于stack exchange,提问作者CastoldiG
相关产品推荐
相关产品推荐

