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

Flutter Isolate重复启动报错:Bad state: Stream已被监听

你遇到的Bad state: Stream has already been listened to错误,核心原因是同一个ReceivePort被重复监听,或者已被关闭后复用。你的代码里_receivePort在initState只初始化一次,第一次启动Isolate时已经监听了它的流,销毁时又关闭了这个端口,再次启动时复用了已失效或已被监听的端口,导致报错。

修复后的完整代码

import 'dart:async';
import 'dart:isolate';
import 'package:flutter/material.dart';

class IsolateExampleWidget extends StatefulWidget {
  @override
  _IsolateExampleWidgetState createState() => _IsolateExampleWidgetState();
}

class _IsolateExampleWidgetState extends State<IsolateExampleWidget> {
  Isolate? _isolate;
  ReceivePort? _receivePort;
  SendPort? _sendPort;
  StreamSubscription? _streamSubscription;

  @override
  void initState() {
    super.initState();
  }

  void _spawnIsolate() async {
    // 避免重复启动Isolate
    if (_isolate != null) return;

    // 每次启动都创建新的ReceivePort
    _receivePort = ReceivePort();
    _isolate = await Isolate.spawn(_isolateEntryPoint, _receivePort!.sendPort);
    print("isolate spawning");

    // 监听新的ReceivePort流
    _streamSubscription = _receivePort!.listen((message) {
      if (message is SendPort) {
        _sendPort = message;
      } else {
        print(message);
      }
    });
  }

  void _sendToIsolate() {
    // 先判断SendPort是否可用
    if (_sendPort != null) {
      _sendPort!.send('hello from main thread');
    } else {
      print("Isolate未启动或已销毁");
    }
  }

  void _killIsolate() {
    // 清理Isolate资源
    _isolate?.kill(priority: Isolate.immediate);
    _isolate = null;
    // 取消流订阅
    _streamSubscription?.cancel();
    _streamSubscription = null;
    // 关闭接收端口
    _receivePort?.close();
    _receivePort = null;
    // 清空发送端口
    _sendPort = null;
    print("killed");
  }

  static void _isolateEntryPoint(SendPort sendPort) {
    final receivePort = ReceivePort();
    sendPort.send(receivePort.sendPort);
    receivePort.listen((message) {
      final String? text = message as String?;
      final String uppercaseText = text?.toUpperCase() ?? '';
      sendPort.send(uppercaseText);
    });
  }

  @override
  void dispose() {
    _killIsolate();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
          onPressed: _spawnIsolate,
          child: const Text('Spawn Isolate'),
        ),
        ElevatedButton(
          onPressed: _sendToIsolate,
          child: const Text('Send to Isolate'),
        ),
        ElevatedButton(
          onPressed: _killIsolate,
          child: const Text('Kill Isolate'),
        ),
      ],
    );
  }
}

关键修改说明

  • 取消initState中初始化_receivePort:改为每次调用_spawnIsolate时创建新的ReceivePort,避免复用已关闭或已被监听的端口。
  • 增加Isolate存活判断:在_spawnIsolate开头检查_isolate != null,防止重复启动。
  • 所有资源改为可空类型:_receivePort、_sendPort、_streamSubscription都设为可空,销毁时置为null,确保下次启动时能重新初始化。
  • 完善_killIsolate的资源清理:销毁时清空所有相关变量,避免残留引用导致的异常。
  • _sendToIsolate增加空安全判断:防止Isolate未启动时调用发送方法崩溃。

内容的提问来源于stack exchange,提问作者Noob Coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:27:17