[Flutter翻译]介绍后台Isolate通道

451 阅读4分钟

介绍背景隔离通道

本文由 简悦SimpRead 转码,原文地址 medium.com

现在从Flutter 3.7开始,我很高兴地宣布,开发人员可以使用插件和平台通道......。

image.png

现在,从Flutter 3.7开始,我很高兴地宣布,开发人员可以从任何隔离区使用插件和平台通道。这一直是我们排名最高的问题之一,自2018年以来一直存在。它被取消了优先级,因为它的实现并不简单,而且有一个解决方法,尽管很麻烦:总是从根隔离区(Flutter提供的隔离区)使用插件。然而,随着Flutter的成熟,它越来越注重性能,遵循古老的软件格言:"让它工作,让它正确,让它快速。" 选择实现这一功能是提高性能和使Flutter更容易使用的一个愉快的交叉点。因此,做出这个投资决定是很容易的。

如果你想看看这个功能是如何使用的,请查看GitHub上的示例代码

为什么会有人想使用后台隔离的插件?嗯,很明显,由于世界上并非所有的代码都是用Dart编写的,所以对插件有一定的需求。社区有多年的努力,使这些代码可以用插件来访问,比如。path_provider 找到临时目录的能力,或者 flutter_local_notifications 发布通知的能力。

下一个合乎逻辑的问题是:"为什么有人会在后台隔离区执行代码?" 答案是,有时你没有选择,一个库可能会在后台隔离区上调用回调,比如 android_alarm_manager_plus 。或者一个应用程序可能正在进行重要的计算,而开发者不希望这些计算干扰到用户界面。

在我帮助谷歌其他团队采用Flutter的过程中,随着产品的成熟,他们最终会进入一个根隔离成为瓶颈的情况,这是不可避免的。所以,我们需要确保框架中的一切都得到优化,并给用户提供工具,在必要时轻松卸载工作。

下面是一个精心设计的背景隔离通道的具体用例。

想象一下,一个用人工智能从文本提示中生成高分辨率图像的应用程序。用户之前的创作存储在Firebase云存储中,并且有一个功能可以从用户的手机中导出和分享创作。Flutter应用程序会启动一个后台隔离程序,从Firebase云存储中下载其图像的8k版本,将图像降频到所需的导出尺寸,将图像保存到相机卷,最后在导出完成后发布本地通知。

在这个例子中,至少有3个插件是从后台隔离通道中使用的,一个是从Firebase云存储中读取,一个是保存到手机的相机卷,还有一个是发布本地通知。如果没有背景隔离通道,应用程序将不得不把8k图像从根隔离区复制到背景隔离区,以便对其进行降频。今天,Dart没有办法使这一操作成为恒定的时间。

下面是一个使用新API从后台隔离区调用 shared_preferences 插件的快速示例。

import ‘package:flutter/services.dart’;
import ‘package:shared_preferences/shared_preferences.dart’;
void main() {
 // Identify the root isolate to pass to the background isolate.
 // (API introduced in Flutter 3.7)
 RootIsolateToken rootIsolateToken = RootIsolateToken.instance!;
 Isolate.spawn(_isolateMain, rootIsolateToken);
}
void _isolateMain(RootIsolateToken rootIsolateToken) async {
 // Register the background isolate with the root isolate.
 BackgroundIsolateBinaryMessenger
   .ensureInitialized(rootIsolateToken);
 // You can now use the shared_preferences plugin.
 SharedPreferences sharedPreferences =
   await SharedPreferences.getInstance();
 print(sharedPreferences.getBool(‘isDebug’));
}

以下是对平台通道工作方式的高度概括。

image.png

当平台通道的结果被调用时,有一个硬编码的跳转到 platform 线程。为了使后台隔离通道发挥作用,必须存储发送消息的隔离体,以便引擎能够在该隔离体的事件循环中安排结果。这是通过使用 Dart的_ports 来实现的。Dart的 ports 存储了拥有它们的隔离体,并且是在这些隔离体上从C API中安排的唯一方法。

另一件需要实现的事情是将背景隔离区与它们的根隔离区联系起来的某种方式。这对我来说是个惊喜,但为了在Flutter引擎被破坏时关闭平台通道,我们必须知道哪些后台隔离器与该引擎相关联。否则,后台隔离器可能试图与正在被销毁的Flutter引擎进行通信。这方面的影响可以在最终的API中看到,必须使用一个 RootIsolateToken 来初始化 BackgroundIsolateBinaryMessenger

关于实现的更多信息,请查看Isolate Platform Channels 设计文档。该文档还包含了反方向通信的建议,这些建议还没有被实施或接受。

感谢Flutter社区的支持,我希望你们都能为这个新功能找到惊人的用途。


www.deepl.com 翻译