Flutter 可以使用compute() 将对象作为消息“发送”吗?

2023-12-26

所以我基本上有一个简单的课程update()方法。但正因为如此update()方法做了一些数学计算,我想用compute()让它在另一个中运行Isolate。计划是运行update()方法中的Isolate并返回更新后的对象,如下所示:

compute(updateAsset, asset).then((value) => asset = value);

Asset updateAsset(Asset asset) {
  asset.update();
  return asset;
}

但后来我得到这个错误:

ArgumentError (Invalid argument(s): Illegal argument in isolate message : (object extends NativeWrapper - Library:'dart:ui' Class: Path))

有没有可能的方法将对象发送到Isolate或者我是否必须发送该值的每一个值Asset as an Integer,创建一个新对象并返回它?


接受的答案现在已经过时了,在 Flutter 3.7 中可以发送的内容似乎有更多的灵活性。这食谱示例 https://docs.flutter.dev/cookbook/networking/background-parsing says:

隔离体通过来回传递消息进行通信。这些消息可以是原始值,例如 null、num、bool、double 或 String,或简单的对象,例如本例中的 List.

如果您尝试在隔离之间传递更复杂的对象(例如 Future 或 http.Response),您可能会遇到错误。

示例代码显示了这一点:

Future<List<Photo>> fetchPhotos(http.Client client) async {
  final response = await client
      .get(Uri.parse('https://jsonplaceholder.typicode.com/photos'));

  // Use the compute function to run parsePhotos in a separate isolate.
  return compute(parsePhotos, response.body);
}

// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();

  return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}

class Photo {
  final int albumId;
  final int id;
  final String title;
  final String url;
  final String thumbnailUrl;

  const Photo({
    required this.albumId,
    required this.id,
    required this.title,
    required this.url,
    required this.thumbnailUrl,
  });

  factory Photo.fromJson(Map<String, dynamic> json) {
    return Photo(
      albumId: json['albumId'] as int,
      id: json['id'] as int,
      title: json['title'] as String,
      url: json['url'] as String,
      thumbnailUrl: json['thumbnailUrl'] as String,
    );
  }
}

有点不清楚“简单对象(例如列表)”的含义 - 什么是简单对象?

The docs https://api.flutter.dev/flutter/dart-isolate/SendPort/send.html对此有更多的了解:

消息的传递对象图可以包含以下对象:

Null
bool
int
double
String
列表、映射或集合(其元素是其中任何一个)
可传输类型数据
发送端口
能力
表示以下类型之一的类型:Object、dynamic、void 或 Never

如果发送者和接收者isolate共享相同的代码(例如通过Isolate.spawn创建的isolate),消息的传递对象图可以包含任何对象,但以下例外:

具有本机资源的对象(例如 NativeFieldWrapperClass1 的子类)。 > 例如,Socket 对象在内部引用附加了本机资源的对象,因此无法发送。

接收端口
动态库
可终结的
终结器
原生终结器
Pointer
UserTag
镜像参考

除了这些例外之外,还可以发送任何对象。被标识为不可变的对象(例如字符串)将被共享,而所有其他对象将被复制。

发送立即发生,并且复制传递对象图可能具有线性时间成本。发送本身不会阻塞(即不会等到接收者收到消息)。一旦其isolate 的事件循环准备好传送消息,相应的接收端口就可以接收消息,而与发送isolate 正在执行的操作无关。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter 可以使用compute() 将对象作为消息“发送”吗? 的相关文章

随机推荐