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

使用Isolate调用函数时触发非法参数异常问题排查

Isolate调用函数抛出不可发送对象异常问题

问题代码

import 'dart:isolate';

import 'package:flutter/material.dart';

void main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final result = await startDownloadUsingRunMethod();
          print('Factorial result: $result');
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }


  Future<String> startDownloadUsingRunMethod() async {
    final imageData = await Isolate.run(_readAndParseJsonWithoutIsolateLogic);
    return imageData;
  }

  Future<String> _readAndParseJsonWithoutIsolateLogic() async {
    await Future.delayed(const Duration(seconds: 2));
    return 'this is downloaded data';
  }
}

抛出异常

E/flutter ( 9611): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: object is unsendable - Library:'dart:async' Class: _AsyncCompleter@4048458 (see restrictions listed at SendPort.send() documentation for more information)

原因分析

问题出在传递给Isolate.run的函数是实例成员方法(_readAndParseJsonWithoutIsolateLogic是_MyHomePageState的成员)。当把实例方法传入隔离区时,会隐式携带当前的_MyHomePageState实例引用,而这个实例包含了大量无法跨隔离区传递的对象(比如Widget状态上下文、异步组件_AsyncCompleter等),这些对象不符合隔离区消息传递的可序列化要求,因此触发异常。

解决方案

将_readAndParseJsonWithoutIsolateLogic改为顶级函数或静态方法,避免携带实例引用:

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

// ... 其他代码保持不变 ...

class _MyHomePageState extends State<MyHomePage> {
  // ... 其他代码保持不变 ...

  Future<String> startDownloadUsingRunMethod() async {
    final imageData = await Isolate.run(_readAndParseJsonWithoutIsolateLogic);
    return imageData;
  }

  // 改为静态方法
  static Future<String> _readAndParseJsonWithoutIsolateLogic() async {
    await Future.delayed(const Duration(seconds: 2));
    return 'this is downloaded data';
  }
}

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

import 'dart:isolate';

import 'package:flutter/material.dart';

// 移到类外部作为顶级函数
Future<String> _readAndParseJsonWithoutIsolateLogic() async {
  await Future.delayed(const Duration(seconds: 2));
  return 'this is downloaded data';
}

void main() async {
  runApp(const MyApp());
}

// ... 其他代码保持不变 ...

class _MyHomePageState extends State<MyHomePage> {
  // ... 其他代码保持不变 ...

  Future<String> startDownloadUsingRunMethod() async {
    final imageData = await Isolate.run(_readAndParseJsonWithoutIsolateLogic);
    return imageData;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 06:00:32