此插件结合了 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.invokeMethod 或 BinaryMessenger.send 方法时,一切都会正常工作。
但是,如果您或您的插件期望通过 MethodChannel.setMethodCallHandler 或 BinaryMessenger.handlePlatformMessage 接收某些数据,您可能会注意到这些方法不起作用。如果您没有从该 Isolate 向平台发送任何数据,则可能会发生这种情况。
为什么?简而言之,原因在于插件仅将来自 Main Isolate 中已知 [method] 通道的所有消息发送到 Combine Isolate。但是,当您向 [method] 通道发送任何内容时,它就会被识别。好消息是,几乎在所有您希望通过 MethodChannel.setMethodCallHandler 或 BinaryMessenger.handlePlatformMessage 方法从通道接收消息的情况下,您首先会向该通道发送一些数据,因此您遇到此问题的可能性非常小。
附加信息
限制可能通过一些很棒的技巧来修复,我稍后会尝试这样做。
您可能已经注意到,此包处于 alpha 版本。这意味着 API 可能会发生变化。 Secondly,这意味着我还有很多事情要做,所以我需要您的帮助。如果您喜欢这个包,请点赞并关注它!如果您有什么想说的,请创建一个 issue!我想知道这个包是否能帮助到任何人。这将给我继续工作的动力?