close

北半球的冬意已至,黃葉與氣溫均隨風而落。年終的最後一個 Flutter 穩定版本 已悄然來到你的面前。讓我們向 Flutter 2.8 打聲招呼~

本次更新包含了 207 位貢獻者和 178 位審核者 的辛勤勞作,所有人共同產出了 2424 個 PR,關閉了 2976 個 issue。在此特別感謝本次發布中最突出的社區貢獻者: 來自 VGV 的 Flutter 開發工程師 Bartosz Selwesiuk,他為 Web 平台的 camera 插件並提交了 23 個 PR。

以上的所有產出讓 Flutter 引擎和開發者工具 (DevTools) 都有了非常顯著的性能提升,同時帶來的還有 Google 移動端廣告 SDK Flutter 版本的穩定版發布、一系列針對 Firebase 的新功能和優化、Flutter WebView 3.0、新的 Flutter Favorite package、向桌面端穩定版邁出的一大步,以及支持更多 package 的新版 DartPad。讓我們一起來看看吧!

性能提升

Flutter 的首要目標是一如既往地保證其質量。我們花費了大量時間以確保 Flutter 在多種多樣的設備上都能流暢且穩定地運行。

應用啟動性能

本次更新優化了應用啟動的延遲。我們在擁有一百萬行以上的代碼量的 GPay 應用上進行了測試,以確保改動在實際生產的應用上有效。這些改動將 GPay在低端 Android 設備上啟動的時間減少了約 50%、高端設備上減少了約 10%。

我們對 Flutter 調用 Dart VM 的 GC 策略也做了一些改進,以此避免在程序啟動期間出現不合時宜的 GC。例如,在 Android 設備上渲染出第一幀前,Flutter 僅在 TRIM_LEVEL_RUNNING_CRITYCAL 及高於其等級的信號出現時,通知 Dart VM 有內存壓力[1]。在本地測試中,低端 Android 設備的初始幀出現間隔時間最多減少了約 300ms。

在先前的 Flutter 版本中,出于謹慎考慮[2],在創建 PlatformView 時會阻塞平台線程。在經過仔細的推理和測試後[3],我們刪除了部分序列化的步驟,使得 GPay 在低端設備上的啟動時間至少減少了 100ms。

長久以來,在初始化首個 Dart isolate 前初始化默認的字體管理器會引入人為的延遲。由於它是首要的延遲瓶頸,所以 將默認字體管理器的初始化延遲[4] 到與首個 Dart isolate 同時運行,降低了啟動的延遲,並讓上述的所有啟動優化的表現更加明顯。

應用內存

由於 Flutter 會儘可能快地加載 Dart VM 的服務 isolate,並將其和綁定在應用內的 AOT 代碼一併加載到內存中,這會導致 Flutter 開發人員在部分內存 有限制的設備上難以追蹤內存指標[5]。在 Flutter 2.8 版本中,Android 設備上 Dart VM 的服務 isolate 已被拆分至單獨的 bundle 中[6],可以單獨加載,減少了在其加載前約 40MB 的內存使用。原本 Dart VM 向操作系統發送 AOT 程序的內存用量的通知,已轉由一個無需多次讀取的文件支持,後續的內存占用量進一步減少了約 10%。因此,先前保存了文件數據拷貝的內存可以回收並用於其他用途。

性能分析

某些場景下,開發者希望能同時看到 Flutter 和 Android 的性能追蹤事件,又或者是在生產模式下查看追蹤事件來更好地了解應用的性能問題。為了這一需求,Flutter 2.8 現在可以選擇在應用啟動後,將性能追蹤事件發送至 Android 的事件記錄器,在生產模式下也同樣如此。

Flutter 性能追蹤事件現在顯示在 Android systrace 記錄工具中(底部)

此外,一些開發人員想要更多的關於光柵緩存行為的性能跟蹤信息,以減少製作動畫效果時的卡頓,這允許 Flutter 快速地對昂貴的、重複使用的圖片進行復用而不是重新繪製。性能跟蹤中的新的 流事件 讓開發人員可以跟蹤光柵緩存圖片的生命周期。

Flutter 開發者工具

對於調試性能問題,新版的開發者工具 (DevTools) 添加了一個新的「增強跟蹤」功能,用來幫助開發者診斷消耗較大的構建、布局和繪製操作引起的 UI 卡頓。

啟用任何一個追蹤功能後,時間軸中將視情況展示 Widget 的構建、RenderObject 布局和 RenderObject 繪製的事件。

此外,新版的開發者工具也增加了應用啟動性能的分析支持。該配置文件包含了從 Dart VM 初始化到第一幀 Flutter 渲染的 CPU 樣本。在你按下「Profile app start up」按鈕並加載應用啟動配置文件後,你將看到為配置文件選擇了「AppStartUp」標籤。你還可以通過在可用用戶標籤列表中選擇此用戶標籤過濾器(如果存在)來加載應用啟動配置文件。選擇此標籤會顯示你的應用啟動的個人資料數據。

Web 平台的平台視圖 (PlatformView)

不僅僅是 Android 和 iOS 平台獲得了性能提升,本次發布同時包含了對 Flutter Web 平台視圖的性能優化。平台視圖是從宿主平台向 Flutter 嵌入 UI 組件的媒介。Flutter Web 使用 HtmlElementView[7] widget 實現了這一功能,讓你能在 Flutter Web 應用中嵌入 HTML 元素。如果你正在使用 google_maps_flutter 插件或 video_player 插件的 Web 版本,或者你正在遵循 Flutter 團隊關於 如何優化網絡上顯示圖像[8] 的建議,那說明你已經在使用平台視圖了。

在之前版本的 Flutter 中,嵌入平台視圖會創建一個新的 canvas,每嵌入一個平台視圖都會新增一個 canvas。創建額外的 canvas 是十分消耗性能的操作,因為每個 canvas 的大小都與整個窗口相等。在 Flutter 2.8 中,將 復用為先前的平台視圖創建的 canvas[9]。因此,你不會在應用的整個生命周期內產生每秒 60 倍的成本,而是只有一次創建的成本。這意味着你可以在 Web 應用中擁有多個 HtmlElementView 實例而不會降低性能,同時還可以減少使用平台視圖時的滾動卡頓。

生態

Flutter 不僅僅是框架、引擎和工具——pub.dev 上現有超過 2w 個與 Flutter 兼容的包和插件,而且每天都在增加。Flutter 開發人員大量的日常操作也是龐大的生態系統的一部分,所以讓我們來看看自上一個版本以來 Flutter 生態系統中有什麼改變。

適用於 Flutter 廣告的 Google 廣告

首先也是最重要的是,Google Mobile SDK for Flutter 已於 11 月正式發布[10]。此版本支持 5 種廣告格式,集成了 AdMob 和 Ad Manager 支持,並包含一個新的中轉功能的測試版,可以幫助你優化廣告展現的效果。有關將 Google Ads 集成到 Flutter 應用以及其他貨幣化選項的更多信息,請查看 Flutter 網站上的頁面[11]。

WebView 3.0

這次 Flutter 附帶的另一個新版本是 webview_flutter 插件[12] 的 3.0 版本。因為新功能的數量增加,我們提升了主要版本號,但也因為 Web 視圖在 Android 上的工作方式可能發生了重大變化。在之前的 webview_flutter 版本中,Hybrid composition 已經可用,但不是默認的。而現在它修復了先前默認以虛擬顯示模式運行的許多問題。根據用戶反饋和我們的問題跟蹤,我們認為是時候讓 Hybrid composition 成為默認設置了。此外,webview_flutter 還增加了一些呼聲極高的功能:

支持使用 POST 和 GET 來加載內容
加載文件或字符串內容為 HTML
支持透明背景
在加載內容前設置 Cookies

此外,在 3.0 版本中,webview_flutter 為新平台提供了初步支持: Flutter Web。已經有很多人要求能夠在 Flutter Web 應用中託管 Web 視圖,這允許開發者利用單個源代碼庫構建移動或 Web 應用。在 Flutter Web 應用中託管 Web 視圖是什麼樣的?從編寫代碼的角度來看,其實是一樣的:

import'package:flutter/foundation.dart';import'package:flutter/material.dart';import'package:webview_flutter/webview_flutter.dart';import'package:webview_flutter_web/webview_flutter_web.dart';voidmain(){runApp(constMaterialApp(home:HomePage()));}classHomePageextendsStatefulWidget{constHomePage({Key?key}):super(key:key);@overrideState<HomePage>createState()=>_HomePageState();}class_HomePageStateextendsState<HomePage>{@overridevoidinitState(){super.initState();//requiredwhilewebsupportisinpreviewif(kIsWeb)WebView.platform=WebWebViewPlatform();}@overrideWidgetbuild(BuildContextcontext)=>Scaffold(appBar:AppBar(title:constText('FlutterWebViewexample')),body:constWebView(initialUrl:'https://flutter.dev'),;}

在 Flutter Web 上運行時,它會按你的預期工作:

請注意,當前 webview_flutter 的 web 實現有許多限制,因為它是使用 iframe 構建的, iframe 僅支持簡單的 URL 加載,無法控制加載的內容或與加載的內容交互。但是,由於需求呼聲太高,我們決定將 webview_flutter_web 作為未經認可的插件提供。如果你想嘗試一下,請將以下內容添加到你的 pubspec.yaml 中:

dependencies:webview_flutter:^3.0.0webview_flutter_web:^0.1.0#顯式依賴未經認可的插件

如果你對 webview_flutter v3.0 有任何反饋,無論是否是關於 Web 平台,請 將問題提交到 Flutter 倉庫中[13]。此外,如果你之前沒有使用過 webview 或者想複習一下,請查看 新的 webview codelab[14],它將帶你逐步完成在 Flutter 應用中託管 Web 內容的過程。

Flutter Favorites 項目

Flutter 生態系統委員會再次召開會議,將以下 package 指定為 Flutter Favorite 的 package:

新路由 API (又名 Navigator 2) 的三個自定義路由 package: beamer[15]、routemaster[16] 和 go_router[17];
drift[18]: 對 Flutter 和 Dart 已經功能強大且流行的響應式持久性庫的重命名,基於 sqlite 構建;
freezed[19]: 一個 Dart「語言補丁」,為定義模型、克隆對象、模式匹配等提供簡單的語法;
dart_code_metrics[20]: 一個幫助您分析和提高代碼質量的靜態分析工具;
以及有着漂亮界面的 package: flex_color_scheme[21]、flutter_svg[22]、feedback[23]、toggle_switch[24] 和 auto_size_text[25]。
使用 flex_color_scheme 構建的可靈活摺疊的應用

祝賀這些 package 的作者,並感謝你通過你的辛勤工作支持 Flutter 社區。如果你有興趣提名你最喜歡的 Flutter package 加入 Flutter Favorite 嘉獎,請按照 Flutter Favorite 計劃頁面[26] 上的指南和說明進行操作。

特定平台的插件

如果你是 package / 插件作者,你需要聲明和實現支持哪些平台。如果你正在使用特定於平台的原生代碼構建插件,你可以 使用項目 pubspec.yaml 中的 pluginClass 屬性[27]來實現,該屬性將指定提供原生功能的原生類名:

flutter:plugin:platforms:android:package:com.example.hellopluginClass:HelloPluginios:pluginClass:HelloPlugin

然而,隨着 Dart FFI 變得更加成熟,有可能使用 100% 的 Dart 實現特定平台的功能,就像 path_provider_windows package[28] 所做的那樣。在這種情況下,你沒有任何本地類可以使用,但你仍然希望將你的插件指定為僅支持某些平台。此時你可以改用 dartPluginClass 屬性:

flutter:plugin:implements:helloplatforms:windows:dartPluginClass:HelloPluginWindows

經過這樣的設置後,即使你沒有任何本機代碼,也可以為特定平台定製插件。你還必須提供 Dart 插件的類,有關詳細內容,你可以在 Flutter 文檔上閱讀 Dart 平台實現文檔[29] 以了解更多。

Firebase 相關的更新

Flutter 生態中另一個重要組成是 FlutterFire,大約有三分之二的 Flutter 應用都在使用它。這次穩定版增加了一系列新的功能,方便開發者們更好的在 Flutter 里使用 Firebase:

所有 FlutterFire 插件都從測試版畢業,「成長」為穩定版
DartPad 開始支持部分 Firebase 服務,方便線上使用和體驗
更方便構建認證和在實時查詢 Firestore 數據的 UI 界面
Flutter 中使用 Firestore Object/Document 映射的支持進入 Alpha 版
生產質量

The FlutterFire plugins[30] 幾乎已經全部從測試版轉為文穩定版,可用於生產環境。

Android、iOS 和網頁版的插件已轉為穩定版,包括 Analytics[31]、Dynamic Links[32]、In-App Messaging[33]、Performance Monitoring[34]、Realtime Database[35]、Remote Config[36] 和 Installations[37]。有些 Firebase 庫本身在部分平台上仍處於測試階段,所以它的 Flutter 插件也會是測試版狀態,比如 App Check 在 macOS 平台。但類似實時數據庫 (Realtime Database)、分析 (Analytics)、遠程配置 (Remote Config) 等 FlutterFire 插件已經在生產環境中可用了,可以選擇試試看!

Firebase 初始化僅需在 Dart 代碼中配置即可

因為這些 package 已經達到生產質量,現在你 只用在 Dart 代碼中配置[38],就可以完成 Firebase 的初始化了。

import'package:firebase_core/firebase_core.dart';import'firebase_options.dart';//generatedvia`flutterfire`CLIFuture<void>main()async{//initializefirebaseacrossallsupportedplatformsWidgetsFlutterBinding.ensureInitialized();awaitFirebase.initializeApp(options:DefaultFirebaseOptions.currentPlatform);runApp(MyApp());}

在 firebase_options.dart 文件中定義的各種配置信息,就可以在選擇的每個支持的平台里初始化 Firebase:

staticconstFirebaseOptionsweb=FirebaseOptions(apiKey:'AIzaSyCZFKryCEiKhD0JMPeq_weJguspf09h7Cg',appId:'1:111079797892:web:b9195888086158195ffed1',messagingSenderId:'111079797892',projectId:'flutterfire-fun',authDomain:'flutterfire-fun.firebaseapp.com',storageBucket:'flutterfire-fun.appspot.com',measurementId:'G-K029Y6KJDX',);

如果你想為每個平台的初始化自定義數據結構的話,請使用這個 flutterfire 命令行工具完成:

這個命令行工具會從每個平台的子文件夾中找到唯一的 bundle ID,進而用它來查找以及創建匹配的特定平台下的 Firebase 工程詳情。這意味着你將省去下載 .json文件到 Android 工程、下載 .plist 文件到 iOS 和 macOS 工程的時間了,當然,也無需再複製粘貼代碼到你的 Web 工程了。換句話說,無論你的應用要為哪些平台初始化 Firebase,這句代碼都可以幫你做到。當然,這也可能不是唯一一處初始化代碼的地方,比如你需要在 Android 或 iOS 中創建 Crashlytics 調試符號 (dSYM) 的時候。但至少可以針對新的 Firebase 工程能夠快速跑起來。

在 DartPad 中使用 Firebase

由於我們可以只在 Dart 代碼中初始化並使用 FlutterFire,那 DartPad 自然也就支持使用 Firebase 啦:

這裡有一個使用 Flutter 和 Firebase 構建的在線聊天的演示,所有這些都可以在 DartPad 中直接使用而無需安裝任何內容。DartPad 對 Firebase 的支持已經包括了核心 API、身份驗證和 Firestore,隨着時間的推進,未來 DartPad 會支持更多 Firebase 服務。

另一個支持是在 FlutterFire 文檔中直接內嵌了 DartPad 實例,比如 Firestore 的示例頁面[39]:

在這個示例中,你將看到 Cloud Firestore 的文檔以及 示例應用[40] 的代碼,並且可以在瀏覽器中直接運行和編輯,無需安裝任何軟件。

Firebase 用戶界面

大多數用戶都有身份驗證的流程,包括但不僅限於通過郵箱和密碼或者第三方賬號登陸等。使用 Firebase 身份認證 (Authentication) 服務,你就可以完成創建新用戶、郵箱認證、重置密碼,甚至是短信兩步驗證、使用手機號碼登錄、將多個賬號合併為一個賬號等功能。直到今天,開發者們仍需要自行來完成這些邏輯和 UI。

今天我們很希望大家嘗試一個新的 package,名為 flutterfire_ui[41]。這個 package 可以用少量的代碼構建一個基本的身份驗證體驗,例如,在 Firebase 項目中設置了使用郵箱和 Google 賬號登陸:

通過這個配置你可以通過下面的代碼構建一個身份驗證:

import'package:flutter/material.dart';import'package:firebase_core/firebase_core.dart';import'package:firebase_auth/firebase_auth.dart';import'package:flutterfire_ui/auth.dart';import'firebase_options.dart';Future<void>main()async{WidgetsFlutterBinding.ensureInitialized();awaitFirebase.initializeApp(options:DefaultFirebaseOptions.currentPlatform);runApp(MyApp());}classMyAppextendsStatelessWidget{constMyApp({Key?key}):super(key:key);@overrideWidgetbuild(BuildContextcontext)=>MaterialApp(home:AuthenticationGate(),);}classAuthenticationGateextendsStatelessWidget{constAuthenticationGate({Key?key}):super(key:key);@overrideWidgetbuild(BuildContextcontext)=>StreamBuilder<User?>(stream:FirebaseAuth.instance.authStateChanges(),builder:(context,snapshot){//Userisnotsignedin-showasign-inscreenif(!snapshot.hasData){returnSignInScreen(providerConfigs:[EmailProviderConfiguration(),GoogleProviderConfiguration(clientId:'xxxx-xxxx.apps.googleusercontent.com',),],);}returnHomePage();//showyourapp’shomepageafterlogin},);}

這段代碼將首先初始化 Firebase,然後會發現用戶尚未登陸進而顯示登錄界面,SigninScreen widget 配置了郵件和 Google 賬號登陸,代碼里還使用了 firebase_auth package 來監測用戶的身份驗證狀態,因此一旦用戶登錄完成,你就可以顯示接下來的應用內容。使用這個代碼片段,你將可以在所有 Firebase 支持的平台上完成身份驗證功能。

再加入一些其他配置的話,你還可以添加一些圖像和自定義文本 (詳情見 本文檔[42]),從而為你提供更全面的用戶身份驗證體驗:

上面這個截圖是移動端的身份認證,不過因為 flutterfire_ui 的 UI 是響應性設計,因此在桌面瀏覽器上,它會是這樣的效果:

用戶可以使用郵箱地址和密碼直接完成登陸,如果他們選擇使用通過谷歌身份驗證登陸,不論是在移動端、Web 端還是桌面端,則將會看到常見的 Google 身份驗證流程。如果用戶還沒有賬戶,他們可以點擊註冊按鈕進入註冊流程。用戶登陸之後就會有電子郵件驗證、密碼重置、登出以及社交賬戶綁定功能。通過電子郵件和密碼的身份驗證適用於所有平台,並支持使用 Google、Facebook 和 Twitter 賬號登陸,以及在 iOS 系統上支持通過 Apple ID 登陸。flutterfire_ui 的身份認證支持多種場景和導航方案以及自定義和本地化選項等。查看 FlutterFire UI 的文檔[43] 了解更多。

此外,身份認證不是 flutterfire_ui 唯一支持的 Flutter UI 的相關功能。它還可以向用戶展示一個來自 Firebase 數據查詢並無限滾動的數據列表,這個版本也包含了一個 FirestoreListView 可以使用:

classUserListViewextendsStatelessWidget{UserListView({Key?key}):super(key:key);//liveFirestorequeryfinalusersCollection=FirebaseFirestore.instance.collection('users');@overrideWidgetbuild(BuildContextcontext)=>Scaffold(appBar:AppBar(title:constText('Contacts')),body:FirestoreListView<Map>(query:usersCollection,pageSize:15,primary:true,padding:constEdgeInsets.all(8),itemBuilder:(context,snapshot){finaluser=snapshot.data();returnColumn(children:[Row(children:[CircleAvatar(child:Text((user['firstName']??'Unknown')[0]),),constSizedBox(width:8),Column(crossAxisAlignment:CrossAxisAlignment.start,mainAxisAlignment:MainAxisAlignment.center,mainAxisSize:MainAxisSize.min,children:[Text('${user['firstName']??'unknown'}''${user['lastName']??'unknown'}',style:Theme.of(context).textTheme.subtitle1,),Text(user['number']??'unknown',style:Theme.of(context).textTheme.caption,),],),],),constDivider(),],);},),);}

實際的運行效果如下:

或者你想為用戶提供對表格數據的增刪改查功能,你可以使用 FirestoreDataTable:

classFirestoreTableStoryextendsStatelessWidget{FirestoreTableStory({Key?key}):super(key:key);//liveFirestorequeryfinalusersCollection=FirebaseFirestore.instance.collection('users');@overrideWidgetbuild(BuildContextcontext){returnFirestoreDataTable(query:usersCollection,columnLabels:const{'firstName':Text('Firstname'),'lastName':Text('Lastname'),'prefix':Text('Prefix'),'userName':Text('Username'),'email':Text('Email'),'number':Text('Phonenumber'),'streetName':Text('Streetname'),'city':Text('City'),'zipCode':Text('Zipcode'),'country':Text('Country'),},);}}

效果是這樣的:

有關身份驗證、列表視圖和數據表的更多信息,請查閱 flutterfire_ui 文檔[44]。這個 package 仍處於預覽狀態,可能會加入更多新的特性,如果你有任何使用的問題或者新的特性需求,請 在 GitHub repo 里參與我們的討論[45]。

Firestore Object/Document 映射 (ODM)

我們同時發布了 Firestore 對象 / 文檔映射 (ODM)[46] 的 Alpha 版本,Firestore ODM 的目標是讓開發者更高效的通過類型安全、結構化對象和方法來簡化 Firestore 的使用。通過生成代碼,你可以以類型安全的方式對數據進行建模,從而改進與文檔和集合交互的語法:

@JsonSerializable()classPerson{Person({requiredthis.name,requiredthis.age});finalStringname;finalintage;}@Collection<Person>(『/persons』)finalpersonsRef=PersonCollectionReference();

有了這些類型,你可以執行類型安全的查詢:

personsRef.whereName(isEqualTo:'Bob');personsRef.whereAge(isGreaterThan:42);

ODM 還支持強類型子集合,也提供了一些內置、優化過的 widget 來重建其 select 功能,你可以在 Firestore ODM 文檔[47] 中閱讀相關內容。因為這個還是 Alpha 版本,請儘可能 在 GitHub repo 里向我們提出反饋[48]。

桌面平台更新

Flutter 2.8 版本在 Windows、macOS 和 Linux 穩定版本的道路上又邁出了一大步。我們的目標質量標準很高,包括國際化和本地化支持,例如 新的中文輸入法支持[49]、韓語輸入法支持[50] 以及剛剛合併的 Kanji(日文)輸入法[51] 支持。或者,就像我們在緊密構建 Windows 輔助功能的支持[52] 一樣。對於 Flutter 來說,在穩定版渠道的桌面端上「運行」是不夠的,它必須在世界各地的語言和文化以及不同能力的設備上運行良好。我們還沒有達到我們想要的目標,但未來可期!

其中一個例子是我們重構了 Flutter 處理鍵盤事件以允許同步響應的架構。這使 widget 能夠處理按鍵並攔截它在整個 widget tree 中的其餘部分中的傳遞。我們在 Flutter 2.5 中完成了這項工作的落地,並在 Flutter 2.8 中修復了許多問題。這是對我們如何處理特定於設備的鍵盤輸入的方式的重新設計,以及和重構 Flutter 處理文本編輯方式的持續工作的補充,所有這些都是用鍵盤這樣輸入密集型的桌面應用所必需的。

此外,我們還在繼續 向 Flutter 擴展視覺密度的定義[53],暴露對話框對齊方式的設置,以便開發者可以實現更加友好的桌面 UI。

最後,Flutter 團隊並不是唯一一個在為了 Flutter desktop 付出心血的團隊。舉個例子,Canonical 的桌麵團隊正在與 Invertase 合作,在 Linux 和 Windows 上開發最流行的 Flutter Firebase 插件。

你可以在 Invertase 博客上[54] 閱讀有關預覽版的更多信息。

DartPad

如果沒有工具的改進,那麼這個 Flutter 新版本的發布是不完整的。我們將重點介紹 DartPad 的改進,其中最大的改進是對更多軟件包的支持。事實上,目前共有 23 個 package 可供導入使用。除了幾個 Firebase 服務之外,該列表還包括諸如 bloc、characters、collection、google_fonts 和 flutter_riverpod 等流行的 package。DartPad 團隊會繼續添加新的 package,如果你想查看當前支持哪些 package 的話,可以單擊右下角的信息圖標。

如果你想了解未來我們向 DartPad 添加新 package 的計劃,請查看 Dart wiki 上的這篇文章[55]。還有另一個新的 DartPad 功能也非常方便,在此之前,DartPad 總是以運行最新的穩定版本運行。在新版本中,你可以使用狀態欄中新的 Channel 菜單 來切換到使用最新的 Beta 渠道版本以及先前穩定版本 (我們稱為 "old channel" 舊渠道)。

DartPad 里舊渠道的使用場景比如你正在撰寫一篇博客文章,而最新的穩定版本還是特別流行,那這將非常有用。

移除 Dev 渠道

Flutter 的發布「渠道」(也就是 channel) 決定了 Flutter 框架和引擎在你的開發機器上變化的速度,stable 代表最少的變更,而 master 代表最多。由於資源有限,我們決定最近將停止更新 dev 渠道。雖然我們確實收到了一些關於 dev 渠道的問題,但我們發現只有不到 3% 的 Flutter 開發人員使用 dev 渠道,因此,我們決定不久將正式停用 dev 渠道。

因為雖然很少有開發人員使用 dev 渠道,但 Flutter 工程師仍需要花費大量時間和精力來維護它。如果你基本都只使用 stable 渠道的 Flutter 版本 (超過 90% 的 Flutter 者都在這麼做),那麼這項改動將不會影響你的日常開發。通過放棄維護這個渠道,開發者們也可以少做一個渠道選擇的決定,同時 Flutter 團隊也可以將時間和精力花在其他事情上。你可以使用 flutter channel 命令來決定你想要哪個渠道。以下是 Flutter 團隊對每個渠道的計劃:

Stable 渠道: 代表我們擁有的最高質量的構建。它們每季度(大致)發布一次,並針對中間的關鍵問題進行熱修復。這是「慢」通道: 安全、成熟、長期服務;
Beta 渠道: 為那些習慣於更快節奏的開發者提供一種快速調整的替代方案。目前每月發布,穩定測試後會發布。這是一個「快速」通道,如果我們發現 dev 渠道相較於 beta 渠道有特別的需求和需求而 beta 渠道無法滿足,我們可能會改變 beta 渠道的計劃來滿足 (比如,加速發布節奏或降低我們對該渠道執行的測試和熱修復級別);
Master 渠道: 是我們活躍的開發渠道。我們不提供對該渠道的支持,但我們針對它運行了一套全面的單元測試。對於對不穩定的構建感到滿意的貢獻者或高級開發者而言,這是適合他們的渠道。在這個頻道上,我們跑得很快,打破了一些東西 (然後會很快地修復它們)。

當我們在未來幾個月停用 dev 渠道時,請考慮使用 beta 或 master 渠道,這取決於你對變更的容忍度以及對使用「最新」還是「最好」的平衡點。

破壞性改動 (breaking changes)

與往常一樣,我們努力減少每個版本中破壞性更改的數量。在此版本中,Flutter 2.8 除了已過期並根據我們的 破壞性改動政策[56] 被刪除的已棄用 API 之外,沒有重大變更。

90292[57] 移除已廢棄的 autovalidate
90293[58] 移除已廢棄的 FloatingHeaderSnapConfiguration.vsync
90294[59] 移除已廢棄的 AndroidViewController.id
90295[60] 移除已廢棄的 BottomNavigationBarItem.title
90296[61] 移除已廢棄的文本輸入格式化類

如果你仍在使用這些 API 並想了解如何遷移代碼,你可以閱讀 Flutter 文檔網站上的遷移指南[62]。與往常一樣,非常感謝社區 貢獻的測試用例[63],幫助我們識別這些破壞性改動。

總結

在我們結束 2021 年並展望 2022 年之際,Flutter 團隊要對整個 Flutter 社區的工作和支持表示感謝。誠然,我們正在為世界上越來越多的開發人員構建 Flutter,但如果沒有你和每位開發者的存在,我們也無法維護並構建它。Flutter 社區與眾不同,感謝你所做的一切!

Miss Kevin!

文內鏈接
[1]

僅在 TRIM_LEVEL_RUNNING_CRITYCAL 及高於其等級的信號出現時,通知 Dart VM 有內存壓力: https://github.com/flutter/flutter/issues/90551

[2]

出于謹慎考慮: https://github.com/flutter/engine/pull/29145#pullrequestreview-778935616

[3]

在經過仔細的推理和測試後: https://github.com/flutter/flutter/issues/91711

[4]

將默認字體管理器的初始化延遲: https://github.com/flutter/engine/pull/29291

[5]

有限制的設備上難以追蹤內存指標: https://github.com/flutter/flutter/issues/91382

[6]

已被拆分至單獨的 bundle 中: https://github.com/flutter/engine/pull/29245

[7]

HtmlElementView: https://api.flutter-io.cn/flutter/widgets/HtmlElementView-class.html

[8]

如何優化網絡上顯示圖像: https://flutter.cn/docs/development/platform-integration/web-images#use-img-in-a-platform-view

[9]

復用為先前的平台視圖創建的 canvas: https://github.com/flutter/engine/pull/28087

[10]

Google Mobile SDK for Flutter 已於 11 月正式發布: https://medium.com/flutter/announcing-general-availability-for-the-google-mobile-ads-sdk-for-flutter-574e51ea6783

[11]

Flutter 網站上的頁面: https://flutter.cn/monetization

[12]

webview_flutter 插件: https://pub.flutter-io.cn/packages/webview_flutter

[13]

將問題提交到 Flutter 倉庫中: https://github.com/flutter/flutter/issues

[14]

新的 webview codelab: https://codelabs.developers.google.com/codelabs/flutter-webview

[15]

beamer: https://pub.flutter-io.cn/packages/beamer

[16]

routemaster: https://pub.flutter-io.cn/packages/routemaster

[17]

go_router: https://pub.flutter-io.cn/packages/go_router

[18]

drift: https://pub.flutter-io.cn/packages/drift

[19]

freezed: https://pub.flutter-io.cn/packages/freezed

[20]

dart_code_metrics: https://pub.flutter-io.cn/packages/dart_code_metrics

[21]

flex_color_scheme: https://pub.flutter-io.cn/packages/flex_color_scheme

[22]

flutter_svg: https://pub.flutter-io.cn/packages/flutter_svg

[23]

feedback: https://pub.flutter-io.cn/packages/feedback

[24]

toggle_switch: https://pub.flutter-io.cn/packages/toggle_switch

[25]

auto_size_text: https://pub.flutter-io.cn/packages/auto_size_text

[26]

Flutter Favorite 計劃頁面: https://flutter.cn/docs/development/packages-and-plugins/favorites

[27]

使用項目 pubspec.yaml 中的 pluginClass 屬性: https://flutter.cn/docs/development/packages-and-plugins/developing-packages#plugin-platforms

[28]

path_provider_windows package: https://pub.flutter-io.cn/packages/path_provider_windows

[29]

Flutter 文檔上閱讀 Dart 平台實現文檔: https://flutter.cn/docs/development/packages-and-plugins/developing-packages#dart-only-platform-implementations

[30]

The FlutterFire plugins: http://firebase.flutter.dev/

[31]

Analytics: https://firebase.flutter.dev/docs/analytics/overview

[32]

Dynamic Links: https://firebase.flutter.dev/docs/dynamic-links/overview

[33]

In-App Messaging: https://firebase.flutter.dev/docs/in-app-messaging/overview/

[34]

Performance Monitoring: https://firebase.flutter.dev/docs/performance/overview

[35]

Realtime Database: https://firebase.flutter.dev/docs/database/overview

[36]

Remote Config: https://firebase.flutter.dev/docs/remote-config/overview

[37]

Installations: https://firebase.flutter.dev/docs/installations/overview

[38]

只用在 Dart 代碼中配置: https://github.com/FirebaseExtended/flutterfire/pull/6549

[39]

Firestore 的示例頁面: https://firebase.flutter.dev/docs/firestore/example/

[40]

示例應用: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore/example

[41]

flutterfire_ui: https://pub.dev/packages/flutterfire_ui

[42]

本文檔: https://firebase.flutter.dev/docs/ui/overview

[43]

FlutterFire UI 的文檔: https://firebase.flutter.dev/docs/ui/overview/

[44]

請查閱 flutterfire_ui 文檔: https://firebase.flutter.dev/docs/ui/overview/

[45]

在 GitHub repo 里參與我們的討論: https://github.com/FirebaseExtended/flutterfire/discussions/6978

[46]

Firestore 對象 / 文檔映射 (ODM): https://firebase.flutter.dev/docs/firestore-odm/overview/

[47]

Firestore ODM 文檔: https://firebase.flutter.dev/docs/firestore-odm/overview/

[48]

在 GitHub repo 里向我們提出反饋: https://github.com/FirebaseExtended/flutterfire/discussions/7475

[49]

新的中文輸入法支持: https://github.com/flutter/engine/pull/29620

[50]

韓語輸入法支持: https://github.com/flutter/engine/pull/24713

[51]

Kanji(日文)輸入法: https://github.com/flutter/engine/pull/29761

[52]

Windows 輔助功能的支持: https://github.com/flutter/flutter/issues/77838

[53]

向 Flutter 擴展視覺密度的定義: https://github.com/flutter/flutter/pull/89353

[54]

Invertase 博客上: https://invertase.io/blog/announcing-flutterfire-desktop

[55]

Dart wiki 上的這篇文章: https://github.com/dart-lang/dart-pad/wiki/Adding-support-for-a-new-package

[56]

破壞性改動政策: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes

[57]

90292: https://github.com/flutter/flutter/pull/90292

[58]

90293: https://github.com/flutter/flutter/pull/90293

[59]

90294: https://github.com/flutter/flutter/pull/90294

[60]

90295: https://github.com/flutter/flutter/pull/90295

[61]

90296: https://github.com/flutter/flutter/pull/90296

[62]

Flutter 文檔網站上的遷移指南: https://flutter.cn/docs/release/breaking-changes/2-5-deprecations

[63]

貢獻的測試用例: https://github.com/flutter/tests/blob/master/README.md

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()