此插件结合了 Isolate 和 MethodChannel。换句话说,它提供了一种在 Isolate 中使用 flutter 插件的方法,或者只是为 Isolate 提供用户友好的 API。

功能

  • 创建一个 Isolate。
  • 无需额外代码即可与 Isolate 通信。
  • 在 Isolate 中使用 Method Channels。
  • 支持所有 Flutter 平台。

❌️ 它不会在 Web 上创建 Isolate 替代品(又名 Service Worker)。因此,所有代码将在单个(主)Isolate 中运行。

用法

创建并维护 Isolate

创建

CombineIsolate 只是 Isolate 的一个表示,因此当您创建 CombineIsolate 时,Isolate 将在后台创建,但 Web 平台除外。

要创建新的 CombineIsolate,您只需要调用 Combine().spawn(entryPointFunction)entryPointFunction 是将在 Isolate 中调用的函数。

CombineIsolate combineIsolate = await Combine().spawn((context) {
  print("Hello from Isolate!!!");
});

监听错误

要监听错误,您可以使用 CombineIsolate.errors getter,它返回一个包含来自 isolate 的错误的流。

CombineIsolate combineIsolate;
combineIsolate.errors.listen(print); // Listen for errors.

终止

要终止 CombineIsolate,您可以使用 CombineIsolate.kill 方法。

CombineIsolate combineIsolate;
combineIsolate.kill(); // Kill Isolate.

与 Isolate 通信

IsolateContext

还记得 entryPointFunction 中的 context 参数吗?让我们仔细看看它。

IsolateContext 包含一个在您生成 Isolate 时传递的参数,以及一个用于与原始 Isolate 通信的 IsolateMessenger

传递参数

要提供参数,只需将其传递给 spawn 函数。

Combine().spawn(
  (context) {
    final argument = context.argument as String;
    print(argument); // Print: This is my argument
  },
  argument: "This is my argument",
);

与 Isolate 聊天

要与 Isolate 聊天,您可以使用 IsolateMessenger。它有一个 messages getter,其中包含来自 Isolate 的消息流,以及一个 send 方法,用于向 Isolate 发送消息。

在创建的 Isolate 中,您可以从 IsolateContext.messenger 获取 IsolateMessenger。另一个 IsolateMessenger 可以在 CombineIsolate 中找到。

CombineIsolate combineIsolate = await Combine().spawn((context) {
  context.messenger
    ..messages.listen(
      (event) => print("Message from Main Isolate: $event"),
    )
    ..send("Hello from Combine Isolate!");
});

combineIsolate.messenger.messages.listen(
  (event) {
    print("Message from Combine Isolate: $event");
    combineIsolate.messenger.send("Hello from Main Isolate!");
  },
);

此代码将产生以下输出

来自 Combine Isolate 的消息:来自 Combine Isolate 的问候!来自 Main Isolate 的消息:来自 Main Isolate 的问候!

处理 MethodChannels

配置

所有配置都已完成,可以与 MethodChannels 一起使用,因此您可以直接使用它们!

Combine().spawn((context) async {
  final textFromTestAsset = await rootBundle.loadString("assets/test.txt");
  print("Text from test asset: $textFromTestAsset");
  // Print: Text from test asset: Asset is loaded!
});

说明

  • 关键在于 rootBundle 使用 BinaryMessenger(低级 MethodChannel)。
  • 假设文件 assets/test.txt 存在并且包含文本 Asset is loaded!

限制

当您或您的插件使用 MethodChannel.invokeMethodBinaryMessenger.send 方法时,一切都会正常工作。

但是,如果您或您的插件期望通过 MethodChannel.setMethodCallHandlerBinaryMessenger.handlePlatformMessage 接收某些数据,您可能会注意到这些方法不起作用。如果您没有从该 Isolate 向平台发送任何数据,则可能会发生这种情况。

为什么?简而言之,原因在于插件仅将来自 Main Isolate 中已知 [method] 通道的所有消息发送到 Combine Isolate。但是,当您向 [method] 通道发送任何内容时,它就会被识别。好消息是,几乎在所有您希望通过 MethodChannel.setMethodCallHandlerBinaryMessenger.handlePlatformMessage 方法从通道接收消息的情况下,您首先会向该通道发送一些数据,因此您遇到此问题的可能性非常小。

附加信息

限制可能通过一些很棒的技巧来修复,我稍后会尝试这样做。

您可能已经注意到,此包处于 alpha 版本。这意味着 API 可能会发生变化。 Secondly,这意味着我还有很多事情要做,所以我需要您的帮助。如果您喜欢这个包,请点赞并关注它!如果您有什么想说的,请创建一个 issue!我想知道这个包是否能帮助到任何人。这将给我继续工作的动力?

GitHub

查看 Github