使用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
相关产品推荐
相关产品推荐

