如何更新Flutter后台服务以获取最新SharedPreferences数据?
问题分析与解决方案
1. 优先修正SharedPreferences数据读取的类型错误
你的代码中存在类型获取逻辑错误,这是导致数据显示异常的核心原因:在后台服务的定时任务里,itemName是存入SharedPreferences的字符串类型,你误用了getDouble方法;amount是浮点类型,却用了getString方法,最终只能拿到默认值,看起来像是没获取到最新数据。
修正后的读取代码:
for (int i = 1; i <= totalCount; i++) { String key = 'TCID$i'; // 修正:itemName为String类型,使用getString String nme = prefs.getString('$key-itemName') ?? ''; // 修正:amount为Double类型,使用getDouble double amt = prefs.getDouble('$key-amount') ?? 0.0; print('TCID $i:'); print(' - Current Radius: $nme'); print(' - Destination Title: $amt'); }
2. 优化后台服务的启动与数据同步逻辑
控制台提示Service already running, using existing service说明服务已在运行,重复启动不会重新初始化服务,此时需要通过消息通知服务读取最新数据,而非重复启动。
步骤一:确保服务初始化仅执行一次
将initializeService()放在main函数中执行,避免在页面中重复调用:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await initializeService(); runApp(const MyApp()); }
步骤二:修改saveDetails的服务调用逻辑
在保存数据后,判断服务状态:已运行则发送刷新消息,未运行则启动服务,同时添加最多3条数据的限制:
Future<void> saveDetails() async { SharedPreferences prefs = await SharedPreferences.getInstance(); int totalCount = prefs.getInt('idCount') ?? 0; // 限制最多3条数据 if (totalCount >= 3) { print("最多只能添加3条详情数据"); return; } int currentCount = totalCount + 1; await prefs.setInt('idCount', currentCount); String key = 'TCID$currentCount'; await prefs.setString('$key-itemName', widget.name); await prefs.setDouble('$key-amount', widget.amount); final service = FlutterBackgroundService(); bool isRunning = await service.isRunning(); if (isRunning) { // 发送消息通知服务立即刷新数据 await service.sendData({'action': 'refresh_data'}); } else { await service.startService(); } }
步骤三:在服务中监听刷新消息
修改onStart函数,添加消息监听,收到刷新指令时立即读取最新数据,同时保留定时任务:
@pragma('vm:entry-point') void onStart(ServiceInstance service) async { WidgetsFlutterBinding.ensureInitialized(); if (service is AndroidServiceInstance) { service.on('setAsForeground').listen((event) { service.setAsForegroundService(); }); service.on('setAsBackground').listen((event) { service.setAsBackgroundService(); }); service.on('stopService').listen((event) { service.stopSelf(); }); // 监听数据刷新指令 service.on('refresh_data').listen((event) { _fetchAndPrintLatestData(); }); } // 保留定时任务,周期性执行数据读取 Timer.periodic(const Duration(seconds: 5), (timer) async { if (service is AndroidServiceInstance) { if (await service.isForegroundService()) { service.setForegroundNotificationInfo( title: "My App Service", content: "Updated at ${DateTime.now()}", ); } } await _fetchAndPrintLatestData(); }); } // 提取数据读取逻辑为独立函数,便于复用 Future<void> _fetchAndPrintLatestData() async { SharedPreferences prefs = await SharedPreferences.getInstance(); int totalCount = prefs.getInt('idCount') ?? 0; print("---------------------Total idCount stored: $totalCount"); for (int i = 1; i <= totalCount; i++) { String key = 'TCID$i'; String nme = prefs.getString('$key-itemName') ?? ''; double amt = prefs.getDouble('$key-amount') ?? 0.0; print('TCID $i:'); print(' - Current Radius: $nme'); print(' - Destination Title: $amt'); } print("----------------------Background task is running"); }
3. 额外注意事项
- 所有SharedPreferences的操作必须使用
await,确保数据持久化完成后再通知服务; - 服务启动后,定时任务会每5秒自动读取最新数据,同时收到刷新消息会立即触发读取,保证数据实时性。
内容的提问来源于stack exchange,提问作者Subin
相关产品推荐
相关产品推荐

