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

Flutter中StatefulWidget使用Dart Isolate报错的问题及解决

Flutter StatefulWidget中使用Isolate报错的原因与解决方法

问题描述

在Flutter中使用Dart Isolate时,StatelessWidget环境下运行正常,但改为StatefulWidget后出现如下错误:

E/flutter ( 3154): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception:
Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:ui' Class: EngineLayer)
E/flutter ( 3154): #0      Isolate._spawnFunction (dart:isolate-patch/isolate_patch.dart:399:25)
E/flutter ( 3154): #1      Isolate.spawn (dart:isolate-patch/isolate_patch.dart:379:7)
E/flutter ( 3154): #2      _TestScreenState.createIsolate test_screen.dart:18
E/flutter ( 3154): #3      _TestScreenState.build.<anonymous closure> test_screen.dart:38
E/flutter ( 3154): #4      _InkResponseState.handleTap ink_well.dart:1096
E/flutter ( 3154): #5      GestureRecognizer.invokeCallback recognizer.dart:253
E/flutter ( 3154): #6      TapGestureRecognizer.handleTapUp tap.dart:627
E/flutter ( 3154): #7      BaseTapGestureRecognizer._checkUp tap.dart:306
E/flutter ( 3154): #8      BaseTapGestureRecognizer.handlePrimaryPointer tap.dart:239
E/flutter ( 3154): #9      PrimaryPointerGestureRecognizer.handleEvent recognizer.dart:615
E/flutter ( 3154): #10     PointerRouter._dispatch pointer_router.dart:98
E/flutter ( 3154): #11     PointerRouter._dispatchEventToRoutes.<anonymous closure> pointer_router.dart:143
E/flutter ( 3154): #12     _LinkedHashMapMixin.forEach (dart:collection patch/compact_hash.dart:625:13)
E/flutter ( 3154): #13     PointerRouter._dispatchEventToRoutes
E/flutter ( 3154): #14     PointerRouter.route
pointer_router.dart:127
E/flutter ( 3154): #15     GestureBinding.handleEvent
binding.dart:460
E/flutter ( 3154): #16     GestureBinding.dispatchEvent
binding.dart:440
E/flutter ( 3154): #17     RendererBinding.dispatchEvent
binding.dart:336
E/flutter ( 3154): #18     GestureBinding._handlePointerEventImmediately
binding.dart:395
E/flutter ( 3154): #19     GestureBinding.handlePointerEvent
binding.dart:357
E/flutter ( 3154): #20     GestureBinding._flushPointerEventQueue
binding.dart:314
E/flutter ( 3154): #21     GestureBinding._handlePointerDataPacket
binding.dart:295
E/flutter ( 3154): #22     _invoke1 (dart:ui/hooks.dart:164:13)
E/flutter ( 3154): #23     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:361:7)
E/flutter ( 3154): #24     _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31)

对应的StatefulWidget代码如下:

import 'dart:async';
import 'dart:isolate';

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget {
  const TestScreen({super.key});

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {

  void createIsolate() async {
    print('Inside createIsolate');
    final p = ReceivePort();
    await Isolate.spawn(_createIsolate, p.sendPort);

    print(await p
        .takeWhile((element) => element is String)
        .take(1)
        .cast<String>()
        .first);
  }

  Future<void> _createIsolate(SendPort p) async {
    print('Spawned isolate started.');
    p.send('This is the message!');
    Isolate.exit();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => createIsolate(),
          child: const Text('Create isolate'),
        ),
      ),
    );
  }
}

错误指向await Isolate.spawn(_createIsolate, p.sendPort);一行,但改为StatelessWidget时能正常输出:

I/flutter ( 3154): Inside createIsolate
I/flutter ( 3154): Spawned isolate started.
I/flutter ( 3154): This is the message!

需求是保留StatefulWidget,并要在initState方法中使用Isolate。

原因分析

问题出在_createIsolate是_TestScreenState类的成员方法:当调用Isolate.spawn(_createIsolate, p.sendPort)时,Dart会隐式地把当前State实例的引用传递给新Isolate,而State对象内部持有和Flutter UI相关的原生包装对象(比如错误日志里的EngineLayer),这类对象属于NativeWrapper,无法跨Isolate传递——Isolate之间只能传递可序列化的对象或SendPort这类允许的通信对象。

而在StatelessWidget中,对应的方法要么是顶层函数,要么是Widget的成员方法,不会绑定包含UI相关原生对象的State实例,因此不会触发这个错误。

解决方案

把_createIsolate改为顶层函数,或者改为State类的静态方法,切断它和State实例的绑定,避免传递不可跨Isolate的对象。

修改后的代码示例(静态方法版本)

import 'dart:async';
import 'dart:isolate';

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget {
  const TestScreen({super.key});

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {

  @override
  void initState() {
    super.initState();
    createIsolate(); // 在initState中调用Isolate
  }

  void createIsolate() async {
    print('Inside createIsolate');
    final p = ReceivePort();
    await Isolate.spawn(_createIsolate, p.sendPort);

    final message = await p
        .takeWhile((element) => element is String)
        .take(1)
        .cast<String>()
        .first;
    print(message);
    p.close(); // 记得关闭ReceivePort,避免内存泄漏
  }

  // 改为静态方法,不再绑定State实例
  static Future<void> _createIsolate(SendPort p) async {
    print('Spawned isolate started.');
    p.send('This is the message!');
    Isolate.exit();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => createIsolate(),
          child: const Text('Create isolate'),
        ),
      ),
    );
  }
}

修改后的代码示例(顶层函数版本)

import 'dart:async';
import 'dart:isolate';

import 'package:flutter/material.dart';

// 顶层函数,脱离State类
Future<void> _createIsolate(SendPort p) async {
  print('Spawned isolate started.');
  p.send('This is the message!');
  Isolate.exit();
}

class TestScreen extends StatefulWidget {
  const TestScreen({super.key});

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {

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

  void createIsolate() async {
    print('Inside createIsolate');
    final p = ReceivePort();
    await Isolate.spawn(_createIsolate, p.sendPort);

    final message = await p
        .takeWhile((element) => element is String)
        .take(1)
        .cast<String>()
        .first;
    print(message);
    p.close();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () => createIsolate(),
          child: const Text('Create isolate'),
        ),
      ),
    );
  }
}

这样修改后,Isolate就能正常在StatefulWidget中运行,包括initState方法里的调用。


内容的提问来源于stack exchange,提问作者sm-sayedi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:48:08