Flutter(一)Hello, Flutter!
1. 移動端開發演變過程
1.1 原生開發
原生應用程式是指某一個移動平臺(比如iOS或安卓)所特有的應用,使用相應平臺支援的開發工具和語言,直接呼叫系統SDK API。
-
Android原生應用:使用Java或Kotlin直接呼叫Android SDK開發的應用程式;
-
iOS原生應用:通過Objective-C或Swift語言直接呼叫iOS SDK開發的應用程式。
主要優勢:
-
可直接無障礙的訪問平臺全部功能;
-
速度快、效能高、可以實現複雜動畫及繪製,整體使用者體驗好;
主要缺點:
-
開發成本高;不同平臺必須維護不同程式碼,人力成本、測試成本大;
-
內容固定,動態化弱,大多數情況下,有新功能更新時只能發版,但應用上架、稽核是需要週期的,這對高速變化的網際網路時代來說是很難接受的;
針對動態化和開發成本兩個問題,誕生了一些跨平臺的動態化框架。👇👇👇👇👇👇
1.2 跨平臺技術簡介
這裡的跨平臺指Android和iOS兩個平臺。根據其原理,主要分為三類:
-
H5+原生(Cordova、Ionic、微信小程式)=> Hybrid/混合開發
-
原理:APP需要動態變化的內容通過H5來實現,進一步通過原生的網頁載入控制元件WebView (Android)或WKWebView(iOS)來載入。
-
WebView實質上是一個瀏覽器核心,其JavaScript依然執行在一個許可權受限的沙箱中,所以對於大多數系統能力都沒有訪問許可權,如無法訪問檔案系統、不能使用藍芽等。所以,對於H5不能實現的功能,都需要原生去做。
-
核心:混合框架會在原生程式碼中預先實現一些訪問系統能力的API, 暴露給WebView以供JavaScript呼叫,讓WebView成為JavaScript與原生API之間通訊的橋樑,主要負責JavaScript與原生之間傳遞呼叫訊息 => JsBridge(WebView JavaScript Bridge)
-
JavaScript開發+原生渲染 (React Native、Weex、快應用)
這裡主要介紹下 React Native 特點
-
和 React 原理相似,支援響應式程式設計,開發者只需關注狀態轉移,不需要關注UI繪製;
-
React 和 React Native 主要的區別在於虛擬DOM對映的物件是什麼:
-
React中虛擬DOM最終會對映為瀏覽器DOM樹;
-
RN中虛擬DOM會通過 JavaScriptCore 對映為原生控制元件樹。(兩步)
-
第一步:佈局訊息傳遞; 將虛擬DOM佈局資訊傳遞給原生;
-
第二步:原生根據佈局資訊通過對應的原生控制元件渲染控制元件樹;
-
優點:
-
採用Web開發技術棧,社群龐大、上手快、開發成本相對較低。
-
原生渲染,效能相比H5提高很多。
-
動態化較好,支援熱更新。
-
不足:
-
渲染時需要JavaScript和原生之間通訊,在有些場景如拖動可能會因為通訊頻繁導致卡頓;
-
JavaScript為指令碼語言,執行時需要JIT(Just In Time),執行效率和AOT(Ahead Of Time)程式碼仍有差距;
-
由於渲染依賴原生控制元件,不同平臺的控制元件需要單獨維護。
( RN架構升級,進行中,解決頻繁和原生通訊的瓶頸問題。)
-
自繪UI+原生(QT for mobile、Flutter)
-
QT for mobile(是移動端開發跨平臺自繪引擎的先驅,也是烈士。)
-
Flutter 👇👇👇👇👇👇
2. Flutter 介紹
Flutter 是 Google 推出並開源的移動應用框架,主打跨平臺、高保真、高效能。
2.1 跨平臺自繪引擎
Flutter 與用於構建應用程式的其他框架不同,是因為 Flutter 既不使用 WebView 也不使用作業系統的原生控制元件。相反,Flutter 自己實現了自繪引擎。這樣不僅能保證一套程式碼可以同時執行在 IOS 和 Android 平臺上,還保證了 Android 和 IOS 上 UI 的一致性,而且也可以避免對原生控制元件依賴帶來的限制和高昂的成本維護,也不用和native層做過多的通訊,大大提高效能。
Flutter 使用 Skia 作為其2D渲染引擎,Skia 是一個 Google 的2D圖形處理函式,包含字元、座標轉換,以及點陣圖都有高效能且簡介的表現,Skia 是跨平臺的,並提供了非常友好的 API ,目前 Google Chrome 瀏覽器和 Android 均採用 Skia 作為其繪圖引擎。
目前 Flutter 預設支援 Android、IOS、Fuchsia(Google新的自研作業系統)、鴻蒙四個移動平臺,也支援 Web 開發(Flutter for web)、 PC 、小程式的開發。
2.2 採用Dart語言
這是一個很有意思也很有爭議的問題,Flutter為什麼選擇Dart語言?
① 開發效率高。Dart執行時和編譯器支援Flutter兩個關鍵特性的組合:
基於JIT的快讀開發週期:Flutter在開發階段採用JIT模式。這樣就避免了每次改動都要進行編譯,極大節省了開發時間;並且在iOS和Android模擬器或真機上可以實現毫秒級熱過載,並且不會丟失狀態。
基於AOT的釋出包:Flutter 在釋出時間可以通過AOT生成高效的ARM程式碼以保證應用效能。而JavaScript則不具有這個能力(雖然可以通過打包工具實現)。
目前,程式主要有兩種執行方式:靜態編譯與動態解釋。
靜態編譯:在執行前全部被翻譯為機器碼
👉 AOT(Ahead of time)即“提前編譯”; AOT程式的典型代表是用C/C++開發的應用,他們必須在執行前編譯成機器碼; 動態解釋(解釋執行)則是一句一句邊翻譯邊執行
👉 JIT(Just-in-time)即“即時編譯”。 JIT的代表則非常多,如JavaScript、Python等。
事實上,所有指令碼語言都支援JIT模式。但需要注意的是,JIT和AOT 指的是程式執行方式,和編譯語言並非強相關,有些語言既可以以JIT方式執行也可以以AOT方式執行,如Java、Python,他們可以在第一次執行時編譯成中間位元組碼,然後在之後執行時可以直接執行位元組碼,也許有人會說,中間位元組碼並非機器碼,在程式執行時仍需動態將位元組碼轉換成機器碼,是的,這沒有錯,不過通常我們區分是否為AOT的標準就是看程式碼在執行前是否需要編譯,只要需要編譯,無論其編譯產物是位元組碼還是機器碼,都屬於AOT(不必糾結於概念,概念是為了傳達精神而發明的,理解原理即可)。
② 高效能。Flutter提供流暢、高保真的UI體驗,為了實現這一點,Flutter中需要能夠在每個動畫幀中執行大量的程式碼。這意味著需要一種既能提供高效能的語言,而不會出現丟幀的週期性暫停的問題,而Dart支援AOT,在這一點上可以比JavaScript做的更好。
③ 型別安全。由於Dart 是型別安全的語言,支援靜態型別檢查,所以可以在編譯前發現一些型別錯誤,並排除潛在問題。這一點對於前端開發者極具吸引力,為了解決JavaScript弱型別的缺點,前端社群出現了很多給JavaScript程式碼新增靜態型別檢測的擴充套件語言和工具,如:微軟的TypeScript、Facebook的Flow。而 Dart 本身就支援靜態型別,這是他的一個重要優勢。
④ 快速記憶體分配。Flutter框架使用函式式流,這使得它在很大程度上依賴底層記憶體分配器。因此,擁有一個能夠有效的處理瑣碎任務的記憶體分配器將顯得十分重要。但其實在記憶體分配上Dart並沒有超越JavaScript,只是Flutter需要,Dart 恰好滿足。
⑤ Dart 團隊就在 Flutter身邊。Dart 語言也是谷歌推出的,由於有Dart團隊的積極投入,Flutter團隊可以獲得更多、更方便的支援。
例如:Dart 最初並沒有提供原生二進位制檔案的工具鏈(這對於實現可預測的高效能有很大幫助),但是現在它實現了,因為 Dart 團隊專門為 Flutter 構建了它。 Dart VM 之前已經針對吞吐量進行了優化,但團隊現在正忙於優化VM的延遲,這對於Flutter的工作負載更為重要。
2.3 高效能
Flutter 高效能主要是靠以上剛剛介紹的兩點來保證的:
① 採用 Dart 語言開發。Dart 在 JIT(即時編譯)模式下,速度與 JavaScript 基本持平,但是 Dart 支援 AOT,當以 AOT 模式執行時,JavaScript 就遠遠追不上了。速度的提升對高幀率下的資料計算很有幫助。
② 使用自己的渲染引擎來繪製 UI,佈局資料由 Dart 語言直接控制,在佈局過程中不需要像 RN 那樣要在 JavaScript 和 Native 之間通訊,這在一些滑動拖動場景下有明顯優勢,因為在滑動和拖動過程中往往都會引起佈局發生變化,所以 JavaScript 需要在 Native 之間不停的同步佈局資訊,這和在瀏覽器中要 JavaScript 頻繁操作 DOM 所帶來的問題是相同的,都會帶來比較大的效能開銷。
2.4 響應式框架
借鑑 React 響應式的 UI 框架設計思想。中心思想是用 widget 構建你的 UI。 Widget 描述了他們的檢視在給定其當前配置和狀態時應該看起來像什麼。當 widget 的狀態發生變化時,widget 會重新構建 UI,Flutter 會對比前後變化的不同, 來確定底層渲染樹從一個狀態轉換到下一個狀態所需的最小更改(類似於 React/Vue 中虛擬 DOM 的 diff 演算法)。
2.5 多端編譯
2.5.1 移動端
-
打包 Android 併發布手機商店 👉 VSCode
-
打包命令
flutter build apk
-
釋出:
-
註冊各大應用市場開發者賬號
-
建立要釋出的app資訊
-
按照流程上傳
-
打包 IOS 併發布 Apple Store 👉 XCode
-
打包命令
flutter build ios
-
釋出:
-
註冊 Apple 開發者
-
建立要釋出的app資訊
-
配置鑰匙串
-
在xcode配置apple stoer的證書和bundle id
-
xcode>Product>Archive>Distribute App
2.5.2 Web端
-
Flutter 2.x
-
檢查是否支援web開發 $ flutter devices
-
打包命令
flutter build web --web-renderer html # 開啟速度最快,相容性好 flutter build web # 開啟速度一般,相容性好 flutter build web --web-renderer canvaskit # 開啟速度最慢,相容性好
-
部署:直接部署到伺服器上即可
3. Flutter 框架結構
3.1 移動架構
3.1.1 Framework 框架層
框架層。這是一個純dart實現的響應式框架,它實現了一套基礎庫。
-
底下兩層(Foundation、Animation、Painting、Gestures)在Google的一些影片中被合併為一個Dart UI層,對應的是Flutter中的dart:ui包,它是Flutter引擎暴露的底層UI庫,提供動畫、手勢及繪製能力。
-
Rendering 層,是一個抽象層,它依賴於 Dart UI ,這一層會構建一個UI樹,當UI有變化時,會計算出有變化的部分,然後更新UI樹,最終將UI樹繪製到螢幕上,這個過程類似於React中的虛擬dom。Rendering層可以說是Flutter UI 框架的核心,它除了確定每個UI元素的位置、大小之外,還要呼叫底層dart:ui進行座標變化和繪製。
-
Widgets層是Flutter提供的一套基礎元件
-
Material 和 Cupertino 是 Flutter 提供的兩種視覺風格的元件庫,Material 安卓風格,Cupertino 是IOS風格。
實際開發過程中,主要都是和最上面的Widgets、Material/Cupertino兩層打交道。
3.1.2 Engine 引擎層
純C++實現的SDK,為Flutter的核心,提供了Flutter核心API的底層實現。其中包括了Dart執行時、Skia引擎、文字排版引擎等,是連線框架和系統(Android/IOS)的橋樑。在程式碼呼叫dart:ui庫時,呼叫最終會走到Engine層,然後實現真正的繪製邏輯。
3.1.3 Embedder 嵌入層
嵌入層基本是由平臺對應的語言來實現的。例如:在Android上,是由Java和C++ 來實現的,IOS是由Object-C和Object-C++來實現的。
嵌入層為Flutter提供了一個入口,Flutter系統是通過該入口訪問底層系統提供的服務,例如輸入法、繪製surface等。
3.2 Web端架構
3.3 移動端開發方式架構比較
4. 移動端開發對比
4.1 方案對比
4.2 效能對比
感興趣 這裡 有詳細的效能對比介紹,不贅述。
5. Flutter 周邊——除錯工具
Flutter日誌 和 print(); 是比較常用的檢查資料的除錯方法,但是不支援圖形化介面、佈局等的檢查。👇👇👇👇👇👇
5.1 inspector 外掛
視覺化和瀏覽Flutter Widget樹的工具。檢視渲染樹,瞭解佈局資訊。
5.2 Dev Tools
5.3 UME
位元組 Flutter Infra 團隊推出的開源 應用內 除錯工具。
Pub.dev 釋出地址
https://pub.flutter-io.cn/packages/flutter_ume
GitHub 開源地址
https://github.com/bytedance/flutter_ume
功能 => UI 檢查、程式碼檢視、日誌檢視、效能工具 ...
服務於 => 設計師、產品經理、研發工程師或質量工程師 ...
- UI 檢查外掛包。點選 widget 獲取 widget 基本資訊、程式碼所在目錄、widget 層級結構、RenderObject 的 build 鏈與描述的能力,顏色拾取與對齊標尺在視覺驗收環節提供有力幫助。
- 程式碼檢視外掛。允許使用者輸入關鍵字,進行模糊匹配,對任意程式碼內容的檢視能力。
- 日誌檢視。日誌資訊可通過統一面板提供篩選、匯出等。
- 效能檢測包。提供了當前 VM 物件例項數量與記憶體佔用大小等資訊。
6. Flutter 周邊——學習路線
6.1 學習社群
-
Flutter 中文網 👉 入門文件
-
Flutter 中文社群 👉 入門文件
-
鹹魚Flutter 👉 可借鑑的架構方案
-
掘進Flutter 👉 專業性強的部落格
-
StackOverflow 👉 問答社群,我遇到的flutter的問題,這裡的答案最靠譜
-
原始碼及註釋 👉 🙋♂️🙋♂️🙋♂️🙋♂️🙋♂️🙋♂️ 最方便開發時查詢
6.2 學習路線
1、準備期
-
目標:
-
通過學習 Dart 基本語法,瞭解 Flutter 中的 Dart 的基本使用;
-
學習 Flutter 提供的基礎佈局和基本內容元件,完成基本頁面展示。
-
技術點:
-
Dart語法
-
Flutter 基礎元件
-
Material Design
-
Cupertino
> * [Flutter Widget概述](https://flutterchina.club/widgets-intro/) > * [Flutter Layout Widget](https://flutter.dev/docs/development/ui/widgets/layout) > * [Flutter 佈局教程](https://flutterchina.club/tutorials/layout/) > * [Material Design](https://material.io/)
-
Flutter 事件處理
-
Flutter 頁面跳轉
2、入門期
-
目標:瞭解 Flutter 盒模型,手勢,動畫等
-
學習資料:
- Flutter 動畫
- Flutter 手勢
3、進階期
-
目標:掌握 Dart 中的 Stream,能將 Flutter 中的狀態管理使用 Stream 或者其他的響應式程式設計的思想開發
-
技術點:
-
Dart非同步
-
Generator
-
Stream
-
Flutter 中的 StreamBuilder
-
Bloc
-
Provider
-
學習資料:
- Dart generator
- Bloc
- FLutter Bloc
- Flutter 親兒子 Provider
6.3 學習開源專案
UI元件集專案 FlutterUnit
7. Flutter 周邊——JS2Flutter
JS 轉 Dart => JS2Flutter