Flutter 3.7如何在后台Isolate任意位置使用shared_preferences读写数据?
要在应用任意位置(比如initState生命周期)使用Isolate完成SharedPreferences的读写,核心是传递RootIsolateToken给子Isolate,同时利用Isolate的消息通信机制(SendPort/ReceivePort)完成主Isolate与子Isolate的数据交互(因为Isolate之间内存完全隔离,无法直接共享数据)。
完整示例代码
import 'dart:isolate'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; class IsolatePrefsDemo extends StatefulWidget { const IsolatePrefsDemo({super.key}); @override State<IsolatePrefsDemo> createState() => _IsolatePrefsDemoState(); } class _IsolatePrefsDemoState extends State<IsolatePrefsDemo> { ReceivePort? _receivePort; bool? _isDebugValue; @override void initState() { super.initState(); _initIsolateAndReadPrefs(); } void _initIsolateAndReadPrefs() async { // 1. 创建ReceivePort,用于接收子Isolate发回的消息 _receivePort = ReceivePort(); // 2. 获取主Isolate的token final rootToken = RootIsolateToken.instance; if (rootToken == null) { debugPrint("无法获取RootIsolateToken"); return; } // 3. 启动子Isolate,传递token和主Isolate的SendPort await Isolate.spawn( _isolatePrefsHandler, _IsolateMessage( token: rootToken, sendPort: _receivePort!.sendPort, action: "read", key: "isDebug", ), ); // 4. 监听子Isolate的返回消息 _receivePort!.listen((message) { if (message is bool?) { setState(() { _isDebugValue = message; }); } else if (message is String) { debugPrint("操作结果:$message"); } }); } // 写入数据的方法,可在按钮点击等事件中调用 void _writePrefsViaIsolate() async { final rootToken = RootIsolateToken.instance; if (rootToken == null || _receivePort == null) return; await Isolate.spawn( _isolatePrefsHandler, _IsolateMessage( token: rootToken, sendPort: _receivePort!.sendPort, action: "write", key: "isDebug", value: true, ), ); } @override void dispose() { _receivePort?.close(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Isolate读写SharedPreferences")), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("isDebug的值:$_isDebugValue"), const SizedBox(height: 20), ElevatedButton( onPressed: _writePrefsViaIsolate, child: const Text("写入isDebug=true"), ), ], ), ), ); } } // 用于在Isolate之间传递的消息类,必须可序列化 class _IsolateMessage { final RootIsolateToken token; final SendPort sendPort; final String action; final String key; final dynamic value; _IsolateMessage({ required this.token, required this.sendPort, required this.action, required this.key, this.value, }); } // 子Isolate的处理逻辑 void _isolatePrefsHandler(_IsolateMessage message) async { // 初始化BackgroundIsolateBinaryMessenger,关联主Isolate BackgroundIsolateBinaryMessenger.ensureInitialized(message.token); final prefs = await SharedPreferences.getInstance(); switch (message.action) { case "read": final result = prefs.getBool(message.key); message.sendPort.send(result); break; case "write": if (message.value is bool) { await prefs.setBool(message.key, message.value); message.sendPort.send("写入成功"); } break; } // 子Isolate完成任务后自行退出,避免资源占用 Isolate.exit(); }
关键说明
- 消息传递:通过自定义的
_IsolateMessage类传递必要信息(token、通信端口、操作类型、参数),这类类默认支持序列化,无需额外实现。 - 资源管理:在
dispose中关闭ReceivePort避免内存泄漏;子Isolate完成任务后调用Isolate.exit()主动退出。 - 操作扩展性:可扩展
action类型,支持字符串、整数等更多SharedPreferences操作,只需在_isolatePrefsHandler中添加对应分支逻辑。 - 错误处理:实际使用中建议添加try-catch块,捕获SharedPreferences操作异常,并通过
sendPort传递错误信息回主Isolate。
内容的提问来源于stack exchange,提问作者samedhrmn
相关产品推荐
相关产品推荐

