【文章翻譯】How Dart’s null safety helped me augment my projects
【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】
原文:https://medium.com/dartlang/how-darts-null-safety-helped-me-augment-my-projects-af58f8129cf
我將一個正在執行的應用程式和一個已發佈的套件遷移到空安全,體驗太棒了!
關於作者: Waleed Arshad 是一位核心行動技術專家,也是一位充滿熱情的跨平台開發者,更是巴基斯坦第一位獲得 Flutter Google 開發專家認證的人。從卡拉奇 FAST 畢業後,他在業界工作了五年多,目前在 Tendermint 的 Flutter 開發者體驗團隊工作。他同時也領導著巴基斯坦的 Flutter 社群。
【文章翻譯】Improving Platform Channel Performance in Flutter
【文章內容使用 Gemini 1.5 Pro 自動產生】

過去幾年,我一直對「如何讓 Flutter 與其主機平台之間的通訊更快、更容易?」這個問題感到興趣。這對 Flutter Plugin 開發人員和增加到應用程式開發人員來說,是一個特別感興趣的問題。
Flutter 與主機平台之間的通訊通常使用 [平台通道](https://flutter.dev/docs/development/platform-integration/platform-channels) 完成,因此我的精力一直集中在這裡。在 2019 年後期,為了解決使用平台通道所需的過多樣板和 [字串類型](https://wiki.c2.com/?StringlyTyped) 程式碼,我設計了一個程式碼產生套件 [Pigeon](https://pub.dev/packages/pigeon),它使平台通道類型安全,並且團隊持續改進它。在 2020 年春季,我對 [平台通道和外部函式介面 (FFI) 效能進行了審查](https://docs.google.com/document/d/1bD_tiN987fWEPtw7tjXHzqZVg_g9H95IS32Cm609VZ8/edit)。現在,我將目光放在 [改進平台通道的效能](https://docs.google.com/document/d/1oNLxJr_ZqjENVhF94-PqxsGPx0qGXx-pRJxXL6LSagc/edit?usp=sharing) 上。由於 Pigeon 建立在平台通道之上,而我計畫在 Pigeon 之上建立一個 [多個 Flutter 實例的資料同步解決方案](http://flutter.dev/go/data-sync),這是一個很好的機會,可以幫助滿足開發人員的許多不同需求,以及我的計劃。
經過一番調查,我能夠識別出透過平台通道傳送的資料的冗餘副本,並且能夠將其移除。您將在下面找到該變更的結果以及識別和移除這些副本的相關工作概述。
結果
在移除透過平台通道從 Flutter 傳送到主機平台的 1 MB 二元資料時,並響應 1 MB 的資料,我們看到 [iOS 上的效能大約提高了 42%](https://flutter-flutter-perf.skia.org/e/?begin=1620764044&end=1621044607&queries=sub_result%3Dplatform_channel_basic_binary_2host_1MB%26test%3Dmac_ios_platform_channels_benchmarks_ios&requestType=0)。在 Android 上,結果稍微複雜一些。我們的自動化效能測試 [大約提高了 15%](https://flutter-flutter-perf.skia.org/e/?begin=1621972627&end=1622677144&queries=sub_result%3Dplatform_channel_basic_binary_2host_1MB%26test%3Dlinux_platform_channels_benchmarks&requestType=0),而本地測試在遷移到新的 [BinaryCodec.INSTANCE_DIRECT](https://github.com/flutter/engine/blob/b3ebb6dd62cefe3c30a7bd15ed73c578030140e2/shell/platform/android/io/flutter/plugin/common/BinaryCodec.java#L27) 編碼器時,[大約提高了 52%](https://github.com/flutter/engine/pull/26331#issuecomment-854071096)。這種差異可能是因為自動化效能測試在舊設備上運行,但也可能是微基準測試在舊設備上的執行方式產生的假象(例如,不斷地讓垃圾收集器執行)。您可以在 [platform_channels_benchmarks/lib/main.dart](https://github.com/flutter/flutter/blob/00bfe9061369bb6fdfe4a74fb27086b77df107bf/dev/benchmarks/platform_channels_benchmarks/lib/main.dart#L165) 中找到自動化效能測試的原始碼。
對於使用 StandardMessageCodec 的平台通道,我發現效能增益較小([使用 14k 負載大約為 5%](https://flutter-flutter-perf.skia.org/e/?begin=1620764044&end=1621044607&queries=sub_result%3Dplatform_channel_basic_standard_2host_large%26test%3Dmac_ios_platform_channels_benchmarks_ios&requestType=0))。我使用一個大型支援類型陣列對其進行測試,以對編碼和解碼進行壓力測試。我發現,MessageCodecs 的編碼和解碼時間遠遠超過在平台之間複製訊息所花費的時間。大部分的編碼時間都是由於對資料結構進行遞迴,並使用反射來找出其內容的成本所致。
因此,根據您使用平台通道的方式和設備,您的結果可能會有很大差異。如果您想要使用平台通道進行最快的通訊,那麼您應該使用 BasicMessageChannels,並在 iOS 上使用 [FlutterBinaryCodec](https://github.com/flutter/engine/blob/b3ebb6dd62cefe3c30a7bd15ed73c578030140e2/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h#L52),在 Android 上使用 [BinaryCodec.INSTANCE_DIRECT](https://github.com/flutter/engine/blob/b3ebb6dd62cefe3c30a7bd15ed73c578030140e2/shell/platform/android/io/flutter/plugin/common/BinaryCodec.java#L27),並為編碼和解碼訊息開發自己的協定,該協定不依賴於反射。(實作新的 MessageCodec 可能更乾淨。)
如果您想試用新的、更快的平台通道,它們現在已在 [master 通道](https://flutter.dev/docs/development/tools/sdk/upgrading#switching-flutter-channels) 上提供。
詳細複製移除
如果您對如何實現這些結果以及我必須克服的問題不感興趣,那麼現在就可以停止閱讀了。如果您喜歡了解詳細資訊,請继续阅读。
平台通道 API 自 2017 年以來沒有太大變化。由於平台通道是引擎和 Plugin 操作的基礎,因此它們不容易更改。雖然我對平台通道的運作方式有一定的了解,但它們在一定程度上是複雜的。因此,改進其效能的第一步是準確地了解它們的運作方式。
下圖概述了框架在使用平台通道與 iOS 進行通訊時從 Flutter 遵循的原始流程:
圖表中的一些收穫:
- 訊息會從 UI 線程跳轉到平台線程,然後再跳回 UI 線程。(在 Flutter 引擎術語中,UI 線程是執行 Dart 的位置,而平台線程是主機平台的主線程。)
- 訊息及其響應使用 C++ 作為介於 Flutter 與主機平台目標語言之間的介面層。
- 訊息的資訊在到達 Objective-C (Obj-C) 處理程式之前被複製了 4 次(步驟 3、5、7、8)。步驟 3 和 8 執行翻譯,而步驟 5 和 8 執行複製,將資料的所有權轉移到新的記憶體佈局。相同的過程反向重複以進行回覆。
- 步驟 1、9 和 16 是使用 Flutter 的開發人員編寫的程式碼。
從 Flutter 傳送訊息到 Java/Kotlin 類似,只是在 C++ 和 Java 虛擬機器 (JVM) 之間有一個 Java 本機介面 (JNI) 層。
在確定平台通道的運作方式後,很明顯,消除在這些層之間傳輸資料時進行的複製(例如,從 C++ 到 Obj-C)是改進效能的顯而易見的方法。為了實現這一點,Flutter 引擎必須將資料放置在記憶體中,以使其可以直接從 Java/Obj-C 存取,並且具有與主機平台相容的記憶體管理語義。
平台通道訊息最終由主機平台的 MessageCodec 的 decodeMessage 方法使用。在 Android 上,這意味著一個 [ByteBuffer](https://github.com/flutter/engine/blob/58459a5e342f84c755919f2ad5029b22bcddd548/shell/platform/android/io/flutter/plugin/common/MessageCodec.java#L38),在 iOS 上,這意味著一個 [NSData](https://github.com/flutter/engine/blob/58459a5e342f84c755919f2ad5029b22bcddd548/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h#L38)。C++ 中的資料必須符合這些介面。在處理此問題時,我發現訊息的資訊儲存在 C++ 記憶體中,作為一個 [std::vector](https://github.com/flutter/engine/blob/70ebfc3610c38c463469ffedea85578f35ccc0a0/lib/ui/window/platform_message.h#L39),位於由 [共用指標](https://en.wikipedia.org/wiki/Smart_pointer) 維護的 PlatformMessage 物件中。這意味著開發人員在將資料從 C++ 傳送到主機平台時,無法安全地移除複製,因為他們沒有保證資料在傳送到主機平台後不會被 C++ 變異。此外,我必須小心,因為 BinaryCodec 實作將 encodeMessage 和 decodeMessage 視為無操作,這可能導致使用 BinaryCodec 的程式碼在不知情的情況下收到直接 ByteBuffer。雖然有人可能會對 MessageCodec 的變更感到意外,但很少有人實作自己的編碼器。另一方面,使用 BinaryCodecs 非常普遍。
在閱讀程式碼後,我發現,雖然 PlatformMessage 由共用指標管理,但它在語義上是唯一的指標。目的是一次只允許一個客戶端存取它(這並不完全是這樣,因為在線程之間傳遞 PlatformMessage 時,暫時會存在多個副本,但这僅僅是为了方便,而并非真正意图)。這意味著我們可以從共用指標遷移到唯一指標,允許我們安全地將資料傳遞到主機平台。
在 [遷移到唯一指標](https://github.com/flutter/engine/commit/7424400f07be684bd87633bbe2d263821181345a#diff-d5a1c9b29bed0d80dc68f228550643925a216e65173364e1ae5a03067b60160d) 後,我必須找到一種方法,將資訊的所有權從 C++ 傳遞到 Obj-C。(我首先實作了 Obj-C,稍後將更詳細地討論 Java)。資訊儲存在一個 std::vector 中,它沒有辦法釋放底層緩衝區的所有權。您唯一的选择是复制出数据、提供一个包含std::vector的适配器、或消除std::vector的使用。
我的第一次嘗試是子類化 NSData,它會 std::move std::vector 並從那裡讀取其資料,從而消除複製。這種嘗試效果不佳,因為結果證明 NSData 是 [Foundation](https://developer.apple.com/documentation/foundation?language=objc) 中的 [類別叢集](https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html)。這意味著您不能只子類化 NSData。在閱讀了許多 Apple 的文件之後,他們似乎建議使用組合和訊息轉發,使物件的行為和外觀像 NSData 一樣。這會欺騙使用代理物件的人,除了那些呼叫 -[NSObject isKindOfClass:] 的人以外。雖然這不太可能,但我無法排除這種可能性。雖然我認為可能有一些與 Obj-C 執行時相關的調整,可以使物件按照我想要的方式運行,但它變得越來越複雜。我選擇將記憶體從 std::vector 移動到 [我們自己的緩衝區類別](https://github.com/flutter/engine/commit/b0bb8eab1d2f7e58230298c28a28ddfeddedeb64#diff-d5a1c9b29bed0d80dc68f228550643925a216e65173364e1ae5a03067b60160d) 中,該類別允許釋放資料的所有權。這樣,我就可以使用 -[NSData dataWithBytesNoCopy:length:] 將資料的所有權傳遞到 Obj-C。
在 Android 上複製這個過程證明更困難。在 Android 上,平台通道符合 ByteBuffer,它具有 [直接](https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html) [ByteBuffers](https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html) 的概念,允許 Java 程式碼直接與以 C/C++ 方式佈局的記憶體進行介面。我在短時間內實作了遷移到直接 ByteBuffers,但我沒有看到預期的改進。我花費了很長時間學習 Android 分析工具,最終選擇了追蹤語句,因為那些工具失敗了,或者返回了我無法相信的結果。事實證明,從平台線程到 UI 線程排程對平台通道訊息的回覆非常慢,而且似乎慢到這種程度,這種減速程度會隨著訊息的負載而增加。長話短說,我在編譯 Dart VM 時使用了錯誤的編譯標誌,以為 -no-optimization 代表 -no-link-time optimization,但該標誌實際上是針對運行時優化的。
在我發現自己的錯誤時,我忘記了在將資料傳送到 Flutter 客戶端程式碼(特別是透過自訂 MessageCodecs 或 BinaryCodec 的客戶端)時使用直接 ByteBuffer 的後果。傳送直接 ByteBuffer 意指您有一個 Java 物件正在與 C/C++ 記憶體進行通訊,因此,如果您刪除 C/C++ 記憶體,那麼 Java 會與隨機垃圾進行交互,並且可能會因作業系統的存取衝突而當機。
效仿 iOS 的做法,我嘗試將 C/C++ 記憶體的所有權傳遞給 Java,以便在 Java 物件被垃圾收集時,它會刪除 C/C++ 記憶體。結果證明,當直接 ByteBuffer 是透過 JNI 透過 [NewDirectByteBuffer](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#NewDirectByteBuffer) 建立時,這是做不到的。JNI 沒有提供在 Java 物件刪除時得知的掛鉤。您無法子類化 ByteBuffer,以便在它被終止時呼叫 JNI。唯一的希望是在上圖中的步驟 5 中從 Java API 分配直接 ByteBuffer。透過 Java 分配的直接 ByteBuffers 沒有這個限制。但是,在 Java 中引入新的入口點將是一個巨大的變革,而且任何使用過 JNI 的人都知道這是很危險的。
相反,我選擇請團隊接受在 decodeMessage 呼叫中使用直接 ByteBuffers。起初,我在 MessageCodec 中引入了一個新的方法,bool wantsDirectByteBufferForDecoding(),以確保沒有人獲得直接 ByteBuffer,除非他們請求它,並且知道其語義(也就是,當底層 C/C++ 記憶體仍然有效時)。這被證明是複雜的,並且令人擔憂的是,開發人員可能會訂閱,但不知道直接 ByteBuffers 的語義,因為它們的運作方式與典型的 ByteBuffers 相反,可能會在他們身下刪除其 C 記憶體支援。儲存編碼的緩衝區是不尋常的使用方式,而且不太可能使用,但團隊無法排除這種可能性。經過多次討論和協商,我們決定每個 MessageCodec 都會獲得一個直接 ByteBuffer,在呼叫 decodeMessage 後會被清除。這樣,如果有人快取編碼的訊息,那麼如果他們在底層 C 記憶體被清理後嘗試使用 ByteBuffer,他們就會在 Java 中得到一個確定性的、適當的錯誤。
讓每個人都能獲得直接 ByteBuffers 效能提升的優點效果很好,但這對 BinaryCodec 來說是一個重大變革,其 encodeMessage 和 decodeMessage 實作是無操作的,它們只是將輸入作為返回值轉發。為了保持 BinaryCodec 的相同記憶體語義,我引入了一個 [新的實例變數](https://github.com/flutter/engine/blob/01d1ed459a313f19e2e01cf8d62331d19b907637/shell/platform/android/io/flutter/plugin/common/BinaryCodec.java#L29),它控制解碼的訊息是直接 ByteBuffer(新的、更快的程式碼)還是標準 ByteBuffer(舊的、更慢的程式碼)。我們無法建立一種方法,讓 BinaryCodec 的所有客戶端都能獲得效能提升。
未來工作
現在已經消除了複製,我下一步改進 Flutter 與主機平台之間通訊的努力是:
- 為 Pigeon 實作自訂 MessageCodec,該編碼器不依賴於反射,以實現更快的編碼和解碼。
- 實作 FFI 平台通道,讓您可以在不跳轉 UI 和平台線程之間的情況下,從 Dart 呼叫主機平台。
我希望您喜歡這次對此效能改進的詳細資訊的深入探討!
改進 Flutter 中的平台通道效能 最初發表在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。
【文章翻譯】Implementing structs by value in Dart FFI
【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】
原文:https://medium.com/dartlang/implementing-structs-by-value-in-dart-ffi-1cb1829d11a9
在 Dart FFI 中實作傳值結構體
在 Dart 2.12 版本中,我們擴充了 C 語言互通功能 Dart FFI,使其能夠 傳值結構體。本文將討論將此功能加入 Dart SDK 的過程。如果您對低階語言實作細節或平台傳值結構體的慣例感興趣,請继续阅读。
【文章翻譯】Announcing Dart 2.13
【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】
原文:https://medium.com/dartlang/announcing-dart-2-13-c6d547b57067
宣佈 Dart 2.13
作者:Kevin Moore 和 Michael Thomsen
今天,我們宣佈推出 Dart 2.13,其中包含類型別名——目前我們第二個最受歡迎的語言功能。Dart 2.13 還包含改進的 Dart FFI 和更好的效能,並且我們有新的 Dart 官方 Docker 映像。這篇文章提供了在 2.12 中引入的空安全功能的更新,討論了新的 2.13 功能,有一些關於 Docker 和 Google Cloud 支援 Dart 後端的令人興奮的消息,並預覽了一些您可以在未來版本中看到的一些變更。
【文章翻譯】What’s new in Flutter 2.2
【文章翻譯】Announcing Flutter 2.2 at Google I/O 2021
【文章內容使用 Gemini 1.5 Pro 自動產生】
原文:https://medium.com/flutter/announcing-flutter-2-2-at-google-i-o-2021-92f0fcbd7ef9
宣布 Flutter 2.2:領先的多平台 UI 工具組的持續發展
在今天的 Google I/O 上,我們宣布了 [Flutter 2.2](https://flutter.dev/docs/whats-new),這是我們開源工具組的最新版本,可以用於從單一平台建立適用於任何設備的精美應用程式。Flutter 2.2 是迄今為止最佳的 Flutter 版本,它提供了更新,使開發人員比以往更容易透過應用程式內購買、付款和廣告來獲利;連接到擴展應用程式以支援新功能的雲端服務和 API;以及工具和語言功能,讓開發人員能夠消除一整類錯誤,提高應用程式效能,並縮減套件大小。
建立在 Flutter 2 的基礎之上
Flutter 2.2 建立在 Flutter 2 的基礎之上,Flutter 2 將 Flutter 從行動端擴展到包含 Web、桌面和嵌入式使用。它專為環境計算世界而設計,在環境計算世界中,使用者擁有各種不同的設備和外形尺寸,並希望獲得跨越他們日常生活的連貫體驗。有了 Flutter 2.2,企業、新創公司和企業家都可以建立高品質的解決方案,這些方案可以發揮其可尋址市場的全部潛力,讓創意靈感(而非目標平台)成為唯一的限制因素。
Flutter 現在是跨平台開發最受歡迎的框架。
最近的一項行動開發人員研究突顯了 Flutter 的成長。分析公司 [SlashData](https://www.slashdata.co/) 的 [2021 年行動開發人員人口預測](https://www.slashdata.co/reports/?category=mobile-desktop) 顯示,Flutter 現在是跨平台開發最受歡迎的框架,45% 的開發人員選擇使用它,從 2020 年第一季到 2021 年第一季成長了 47%。我們自己的數據證實了這種向 Flutter 的轉變;在過去 30 天中,Play 商店中超過八分之一的新應用程式都是使用 Flutter 建立的。
在 I/O 上,我們分享了現在僅在 Play 商店中就有超過 20 萬個應用程式是使用 Flutter 建立的。這些應用程式來自像騰訊這樣的公司,其 [微信](https://apps.apple.com/us/app/wechat/id414478124) 通訊應用程式在 iOS 和 Android 上擁有超過 12 億使用者;[字節跳動](https://www.bytedance.com/en/products/),TikTok 的創始人,他們現在已經使用 Flutter 建立了 70 個不同的應用程式;以及其他來自包括 [BMW](https://www.press.bmwgroup.com/global/article/detail/T0328610EN/the-my-bmw-app:-new-features-and-tech-insights-for-march-2021?language=en)、[SHEIN](https://apps.apple.com/app/id878577184)、[Grab](https://apps.apple.com/app/id647268330) 和 [DiDi](https://play.google.com/store/apps/details?id=com.xiaojukeji.didi.global.customer&hl=None) 等公司的應用程式。當然,Flutter 不僅僅被大型企業使用。一些最具創新性的應用程式來自您可能從未聽說過的名字:例如,[Wombo](https://play.google.com/store/apps/details?id=com.womboai.wombo&hl=None),病毒式的唱歌自拍應用程式;[Fastic](https://play.google.com/store/apps/details?id=de.fastic.app&hl=None),間歇性禁食應用程式;以及 [Kite](https://play.google.com/store/apps/details?id=com.zerodha.kite3&hl=None),一個精美的投資交易應用程式。
介紹 Flutter 2.2
Flutter 2.2 版本重點改進開發體驗,幫助您為客戶提供更可靠、更高效能的應用程式。
聲明性空安全現在是新專案的預設值。空安全增加了對空引用異常的保護,讓開發人員能夠在程式碼中表達非空類型。由於 Dart 的實作是 *聲明性的*,編譯器可以在執行時消除空檢查,為您的應用程式提供更高的效能。生態系統迅速做出回應,大約有 5,000 個套件已經更新以支援空安全。
此版本中也包含許多效能改進:對於 Web 應用程式,我們提供了使用服務工作者的背景快取;對於 Android 應用程式,Flutter 支援延遲組成部分;對於 iOS,我們一直在努力開發工具以預先編譯著色器,以消除或減少第一次運行的卡頓。我們還為 DevTools 套件添加了一些新功能,這些功能可以幫助您了解應用程式中的記憶體分配方式,以及對第三方工具擴展的支援。
此外,我們一直在著手幾個重要的潤色領域,例如改進 Web 目標的可存取性。
我們的發展不僅限於 Flutter 的核心。我們還與其他 Google 團隊合作,幫助將 Flutter 整合到我們更廣泛的開發人員堆疊中。特別是,我們繼續建立值得信賴的服務,幫助開發人員負責任地在應用程式中獲利。此版本中更新了我們的 [新廣告 SDK](https://developers.google.com/admob/flutter/quick-start),包含空安全和對適應性橫幅格式的支援。我們還引入了一個由 Google Pay 團隊合作開發的 [新的付款 Plugin](http://pub.dev/packages/pay),它讓您可以在 iOS 和 Android 上對實體商品進行付款。此外,我們更新了 [應用程式內購買 Plugin](https://pub.dev/packages/in_app_purchase),以及相應的 [Codelab](https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases)。
作為驅動 Flutter 的「秘訣」,[Dart](https://dart.dev) 也在此版本中進行了更新。Dart 2.13 擴展了對原生互操作性的支援,包括在 FFI 中支援陣列和封包結構。它還包括對類型別名的支援,這提高了可讀性,並為某些重構情境提供了一個平緩的路徑。我們繼續為更廣泛的生態系統添加整合,包括一個 Dart [GitHub Action](https://github.com/marketplace/actions/setup-dart-sdk) 和一個經過優化的 [Docker 官方映像](https://hub.docker.com/_/dart),專為雲端部署業務邏輯而設計。
超越 Google 專案
雖然 Google 仍然是 Flutter 專案的主要貢獻者,但我們很高兴看到圍繞 Flutter 的更廣泛生態系統的成長。

在最近幾個月中,Flutter 的成長表現特別突出,它被用於越來越多的平台和作業系統。在 Flutter Engage 上,我們宣布了 [豐田將把 Flutter 带入他們的下一代車輛信息娛樂系統](https://medium.com/googleplaydev/seamless-multi-platform-app-development-with-flutter-ea0e8003b0f9#f53d)。上個月,Canonical 發佈了他們的首個 [帶有整合 Flutter 支援的 Ubuntu](https://ubuntu.com/blog/ubuntu-21-04-is-here),具有 Snap 整合和對 Wayland 的支援。
兩位新合作夥伴證明了這個不斷發展的生態系統。[三星正在將 Flutter 移植到 Tizen](https://github.com/flutter-tizen/flutter-tizen), 開源儲存庫可供其他人貢獻。而 [索尼正在帶頭努力為嵌入式 Linux 提供解決方案](https://github.com/sony/flutter-embedded-linux)。
設計師也從這個專案的開源性質中受益,[Adobe 宣布了其更新的 XD to Flutter 外掛](https://medium.com/adobetech/announcing-xd-to-flutter-v2-0-82d09f3909a7)。Adobe XD 為設計師提供了一個很好的方式來實驗和迭代。現在,隨著增強的 Flutter 支援,設計師和開發人員可以在相同的資產上進行合作,讓好點子更快地投入生產。
最後,微軟繼續與我們合作;除了 Surface 團隊一直在努力使用 Flutter 建立可折疊體驗之外,本週還推出了為 Windows 10 建立的 [Flutter 對 UWP 應用程式的 Alpha 版支援](https://flutter.dev/desktop#windows-uwp)。我們很高兴看到更多利用 Flutter 中內建的平台適應來提供跨行動、桌面、Web 和其他平台的優質體驗的應用程式。
建立出色的體驗
最重要的是,我們建立 Flutter 是為了幫助開發人員建立出色的體驗。我們熱衷於這樣的想法:應用程式開發可以變得更好;我們可以透過消除傳統的障礙來讓您接觸到您的受眾,來賦予您力量。
我們喜歡看到您如何將 Flutter 運用於實際工作中。一個例子來自美國退伍軍人事務部的一個專案。下面的影片顯示了他們的 Flutter 應用程式如何幫助他們為患有創傷後壓力症候群的士兵提供康復服務。
Google I/O 上有 [關於 Flutter 的各種研討會、簡報和隨選課程](https://events.google.com/io/program/content?4=topic_flutter),我們很高興能與大家分享我們的成果。不要忘記查看我們用 Flutter 建立的有趣的 [照片亭 Web 應用程式](https://photobooth.flutter.dev),它讓您能夠與我們的 Dash 吉祥物和她的朋友們合照自拍!
【文章翻譯】How It’s Made: I/O Photo Booth
【文章內容使用 Gemini 1.5 Pro 自動產生】
原文:https://medium.com/flutter/how-its-made-i-o-photo-booth-3b8355d35883
深入探討使用 Flutter 和 Firebase 建立 Web 應用程式
我們(Very Good Ventures 的團隊)與 Google 合作,為今年的 Google I/O 帶來了互動式體驗:一個 照片亭!您可以與知名的 Google 吉祥物合影: Flutter 的 Dash、Android Jetpack、Chrome 的 Dino 和 Firebase 的 Sparky,並使用貼紙裝飾照片,包括派對帽、披薩、時髦眼鏡等等。最後,您可以將照片分享到社交媒體,並下載它們以更新您的活動個人檔案照片!
【文章翻譯】Which factors affected users’ decisions to adopt Flutter? — Q1 2021 user survey results
【文章內容使用 Gemini 1.5 Pro 自動產生】
哪些因素影響了使用者採用 Flutter 的決定?— 2021 年第一季使用者調查結果
Flutter 團隊在此分享本季使用者調查的結果!本季,我們在 3 月 5 日至 11 日期間,歷時 7 天,收集了超過 8,000 份回覆。這個季度的調查計畫旨在以結構化的形式聽取您的意見,以便 Flutter 團隊能夠專注於對使用者最重要的方面。先前調查的結果也發佈在 Medium 上。
【文章翻譯】AngularDart, Flutter, and the web: Spring update
【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】
原文:https://medium.com/dartlang/angulardart-flutter-and-the-web-spring-update-f7f5b8b10001
AngularDart、Flutter 與網路:春季更新
兩個月前,我們發布了 Flutter 網路支援的首個穩定版本。這對整個客戶端開發來說是一個重要的里程碑,它結合了 Flutter 建立的 UI 框架、Dart 工業級強度的 JavaScript 工具鏈以及 Web 平台的底層能力,在行動裝置和瀏覽器之間提供一致性。