Flutter Android应用FCM后台存SharedPreference 仅按返回键退出才可读取?
问题根因
该问题由shared_preferences库的内存缓存机制与FCM后台回调的独立执行上下文共同导致:
shared_preferences默认会将已加载的键值对缓存在当前进程内存中,常规读取操作优先读取缓存,不会每次都访问磁盘文件。- Android平台的FCM后台消息处理器
firebaseMessagingBackgroundHandler运行在独立执行环境,它写入SharedPreferences的操作只会更新磁盘存储,不会同步更新后台挂起的前台应用的内存缓存。 - 按Home键退到后台后应用进程并未销毁,内存缓存仍保留旧数据(
myKey对应值为null),首次切回前台读取时会读到缓存的空值。按返回键退出会销毁整个应用进程,下次启动时shared_preferences会重新从磁盘加载全量数据,因此可以读到后台写入的内容。
解决方案
方案1:读取前强制刷新缓存(推荐,针对性强)
读取后台可能修改的键值前,主动调用reload()方法同步磁盘最新数据到内存缓存:
@override void initState() { super.initState(); WidgetsBinding.instance?.addPostFrameCallback((_) async { final prefs = await SharedPreferences.getInstance(); // 强制从磁盘刷新缓存 await prefs.reload(); final savedValue = prefs.getString("myKey"); print(savedValue); }); }
方案2:切回前台时全局刷新缓存(适合多场景读取的情况)
如果应用多处需要读取后台写入的SharedPreferences数据,可以监听应用生命周期,在切回前台时统一刷新缓存:
class _HomePageState extends State<HomePage> with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance?.addObserver(this); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); // 应用从后台切回前台时刷新缓存 if (state == AppLifecycleState.resumed) { SharedPreferences.getInstance().then((prefs) => prefs.reload()); } } @override void dispose() { WidgetsBinding.instance?.removeObserver(this); super.dispose(); } }
内容的提问来源于stack exchange,提问作者Agung
相关产品推荐
相关产品推荐

