Flutter 3.7 發佈,本人對其中後臺 isolate 通道比較感興趣,迫不及待翻譯了下Aaron Clarke文章,第一次翻譯,有不足地方歡迎各位大佬們評論區指正,我將持續更新到本文,謝謝。 原文地址:Introducing background isolate channels | by ...
Flutter 3.7 發佈,本人對其中後臺 isolate 通道比較感興趣,迫不及待翻譯了下Aaron Clarke文章,第一次翻譯,有不足地方歡迎各位大佬們評論區指正,我將持續更新到本文,謝謝。
原文地址:Introducing background isolate channels | by Aaron Clarke | Flutter | Jan, 2023 | Medium
介紹後臺 isolate 通道
此時此刻,我很高興地宣佈從 Flutter 3.7 開始開發人員可以在任意 isolate 中使用插件和平臺通道了。 這是自 2018 年以來一直存在並且也是我們排名最高的問題之一。它被降低了優先順序,因為實現並不容易且已存在解決方案,儘管很麻煩:始終在 root isolate(Flutter 提供的 isolate)中使用插件 . 然而,隨著 Flutter 的日益成熟,越來越關註性能,俗話說“讓它工作,讓它正確,讓它快速”。 選擇實現這一特征有利於提高性能和易用性。 因此,考慮帶來的收益我們決定實現這一特性。
如果您想瞭解如何使用此特性,請查看 GitHub 上的示例代碼(PS: 原文示例代碼不可用,這裡我用另外一個官方大佬示例代替了。)。
用例
為什麼有人想在後臺 isolate 中使用插件呢?很明顯,因為世上並不是所有代碼都是用 Dart 編寫的。社區多年來一直致力於使用插件來訪問代碼(非 Dart 實現),例如 path_provider 找到臨時目錄的能力或 flutter_local_notifications 發佈通知的能力。
另外一個問題是:為什麼有人在後臺線程中執行代碼呢?因為有時您別無選擇,庫可能正調用後臺 isolate 回調,例如 android_alarm_manager_plus。或者某個應用可能正在進行大量計算,而開發人員不希望這些計算影響 UI。
在我幫助谷歌其他團隊使用 Flutter 的過程中,隨著產品的演進,最終會不可避免地遇到 root isolate 瓶頸。 因此,我們需要確保在框架中優化,併為開發者提供工具使其在必要時做更少的事。
下麵是後臺 isolate 一個人為的用例:
試想,一個應用程式可通過人工智慧根據文本提示生成高解析度圖像。用戶之前創作都被存儲在 Firebase Cloud 中,需求是用戶可以用手機隨時分享創作。該 Flutter 應用啟動時會開啟一個後臺 isolate 從 Firebase Cloud Store 下載 8K 文本提示相關圖片,將圖像壓縮至指定規格大小導出,保存到相冊,最後導出完成併發送通知。
在此示例中,後臺 isolate 至少使用了 3 個插件,一個用於從 Firebase Cloud Storage 中請求數據;接著保存到手機相冊,保存完畢發送本地通知告訴用戶。如果沒有後臺通道,該應用不得不在 root isolate 中拷貝 8k 圖像到後臺 isolate 中進行採樣,當前 Dart 版本沒法保證拷貝過程時間是不變的。
快速開始
下麵是一個使用新 API 在後臺 isolate 中調用 shared_preferences 插件的示例:
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
//root isolate傳給後臺isolate標誌
//(API開始從Flutter3.7)
RootIsolateToken rootIsolateToken = RootIsolateToken.instance!;
Isolate.spawn(_isolateMain, rootIsolateToken);
}void _isolateMain(RootIsolateToken rootIsolateToken) async {
// 將後臺isolate註冊為root isolate
BackgroundIsolateBinaryMessenger
.ensureInitialized(rootIsolateToken);
//你現在可以用shared_preferences插件了。
SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
print(sharedPreferences.getBool(‘isDebug’));
}
技術細節
下麵是平臺通道工作原理概述:
當平臺通道被調用產生結果時將通過硬編碼轉到 platform 線程。為了保證後臺 isolate 正常運行,發送消息的 isolate 應該被持有,以便引擎可以在該 isolate 的事件迴圈上調度結果,這是通過Dart’s ports來實現的,Dart ports 存儲並持有 isolate,這也是通過 C Api 調用這些 isolate 的唯一方式。
其他需要實現的功能是將後臺 isolate 與 root isolate 關聯起來。這是令我驚訝的,為了在引擎銷毀時關閉平臺通道,我們應該知道與引擎關聯的後臺 isolate,否則後臺 isolate 可能與正在銷毀引擎通信,這樣做的效果可以在最終的 API 中看到,必須使用 RootIsolateToken 來初始化BackgroundIsolateBinaryMessenger。
有關實現的更多信息,請查看Isolate Platform Channels設計文檔。文檔中也包含了相左的溝通建議,但尚未付諸實施或接受。
感謝 Flutter 社區的支持,我希望你們都能找到這個新特性更驚艷的用途。
如果覺得文章對你有幫助,點贊、收藏、關註、評論,一鍵四連支持,你的支持就是我創作最大的動力。
❤️ 本文原創聽蟬 公眾號:碼里特別有禪 歡迎關註原創技術文章第一時間推送 ❤️