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

Flutter 3.7如何在后台Isolate任意位置使用shared_preferences读写数据?

如何在Flutter任意位置(如initState)使用Isolate读写SharedPreferences

要在应用任意位置(比如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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:30:44