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

Flutter用AndroidAlarmManagerPlus更新SharedPreferences取不到最新值问题

问题根因
  • AndroidAlarmManager的回调运行在独立Dart Isolate中,与应用主Isolate内存完全隔离,二者的SharedPreferences内存缓存不互通。
  • 后台Isolate更新的是持久化存储中的数据,主Isolate的SharedPreferences缓存仍保留应用进入paused状态前的旧值,因此resumed时读取拿到旧数据,只有应用销毁重启清空缓存后才能读取到最新值。
解决方案

方案1:读取前强制同步持久化数据(最简便)

修改你的Utils.getInt工具方法,读取前调用SharedPreferences的reload()方法,强制同步磁盘上的最新数据,清空当前Isolate的内存缓存:

// 修改Utils类的getInt实现
static Future<int?> getInt(String key) async {
  final sp = await SharedPreferences.getInstance();
  // 同步磁盘最新数据到当前Isolate
  await sp.reload();
  return sp.getInt(key);
}

该方案实现成本极低,适合SP读取频率不高的场景。

方案2:Isolate通信同步缓存(性能更优)

后台Isolate执行完updateTime的存储逻辑后,通过SendPort向主Isolate发送更新通知,主Isolate收到通知后更新自身缓存或本地变量,无需每次读取都刷磁盘,性能更好,适合高频读写的场景。

额外优化点

当前代码每次进入paused状态都会重复注册同ID的周期闹钟,建议注册前先取消已存在的同ID任务,避免重复触发:

update(int id, Function callback) async {
  // 先取消已有同ID闹钟,避免重复注册
  await AndroidAlarmManager.cancel(id);
  print('alram: started ${DateTime.now()}');
  final value = await AndroidAlarmManager.periodic(
    Duration(minutes: 1),
    id,
    callback,
    allowWhileIdle: true,
    exact: true,
    wakeup: true,
  );
  print('is alarm on? $value');
}

内容的提问来源于stack exchange,提问作者Mohammad Safayet Latif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:15:03