Flutter核心技術與實戰

XingJimmy發表於2019-10-28

01 | 預習篇 從0開始搭建Flutter工程環境

準備工作

安裝 Android Studio

配置完成後,我們開啟 AVD Manager,點選“Create Virtual Device”按鈕建立一臺 Nexus 6P 模擬器,至此 Android Studio 的安裝配置工作就完成了。

安裝 Xcode

配置完成後,我們開啟 Terminal,輸入命令open -a Simulator開啟 iOS 模擬器,檢查 Hardware>Device 選單項中的設定,並試著在不同的模擬器之間做切換。

安裝 Flutter

配置Flutter環境變數

如何在模擬器和真機中執行 Flutter 專案。

一、命令列方式

進入Flutter工程目錄 輸入flutter emulator命令,會顯示當前可用的模擬器

flutter emulators --launch apple_ios_simulator (啟動模擬器)
flutter run (執行專案)
複製程式碼

二、配置 Android 和 iOS 的整合開發環境。

Flutter 提供了一個命令flutter doctor協助我們安裝 Flutter 的工程依賴,它會檢查本地是否有 Android 和 iOS 的開發環境,如果檢測到依賴缺失,就會給出對應依賴的安裝方法。

遇到的坑

mac環境還可能提示CocoaPods相關錯誤,如CocoaPods has installed but not initialized,提示你使用執行命令pod setup。但是執行後會發現,過程非常緩慢,基本以失敗告終。

cd ~/.cocoapods/repos
git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git master
或 git clone https://gitclub.cn/CocoaPods/Specs.git master 
複製程式碼

02 | 預習篇 Dart語言概覽

Dart 的特性

JIT和AOT

Dart 是少數同時支援 JIT(Just In Time,即時編譯)和 AOT(Ahead of Time,執行前編譯)的語言之一。

JIT 和 AOT 則是最常見的兩種編譯模式。

  • JIT 在執行時即時編譯,在開發週期中使用,可以動態下發和執行程式碼,開發測試效率高,但執行速度和執行效能則會因為執行時即時編譯受到影響。
  • AOT 即提前編譯,可以生成被直接執行的二進位制程式碼,執行速度快、執行效能表現好,但每次執行前都需要提前編譯,開發測試效率低。

在開發期使用 JIT 編譯,可以縮短產品的開發週期。

而在釋出期使用 AOT,就不需要像 React Native 那樣在跨平臺 JavaScript 程式碼和原生 Android、iOS 程式碼之間建立低效的方法呼叫對映關係。

記憶體分配與垃圾回收(重點)

Dart VM 的記憶體分配策略比較簡單,建立物件時只需要在堆上移動指標,記憶體增長始終是線性的,省去了查詢可用記憶體的過程。

在 Dart 中,併發是通過 Isolate 實現的。Isolate 是類似於執行緒但不共享記憶體,獨立執行的 worker。這樣的機制,就可以讓 Dart 實現無鎖的快速分配。

Dart 的垃圾回收,則是採用了多生代演算法。新生代在回收記憶體時採用“半空間”機制,觸發垃圾回收時,Dart 會將當前半空間中的“活躍”物件拷貝到備用空間,然後整體釋放當前空間的所有記憶體。回收過程中,Dart 只需要操作少量的“活躍”物件,沒有引用的大量“死亡”物件則被忽略,這樣的回收機制很適合 Flutter 框架中大量 Widget 銷燬重建的場景。

單執行緒模型

支援併發執行執行緒的高階語言(比如,C++、Java、Objective-C),大都以搶佔式的方式切換執行緒,即:每個執行緒都會被分配一個固定的時間片來執行,超過了時間片後執行緒上下文將被搶佔後切換。如果這時正在更新執行緒間的共享資源,搶佔後就可能導致資料不同步的問題。

解決這一問題的典型方法是,使用鎖來保護共享資源,但鎖本身又可能會帶來效能損耗,甚至出現死鎖等更嚴重的問題。

這時,Dart 是單執行緒模型的優勢就體現出來了,因為它天然不存在資源競爭和狀態同步的問題。這就意味著,一旦某個函式開始執行,就將執行到這個函式結束,而不會被其他 Dart 程式碼打斷。所以,Dart 中並沒有執行緒,只有 Isolate(隔離區)。Isolates 之間不會共享記憶體,就像幾個執行在不同程式中的 worker,通過事件迴圈(Event Looper)在事件佇列(Event Queue)上傳遞訊息通訊。

無需單獨的宣告式佈局語言

在 Flutter 中,介面佈局直接通過 Dart 編碼來定義。Flutter 並不需要類似 JSX 或 XML 的宣告式佈局語言。

深入理解跨平臺方案的歷史發展邏輯

跨平臺開發方案的三個時代

根據實現方式的不同,業內常見的觀點是將主流的跨平臺方案劃分為三個時代。

  • Web 容器時代 主要採用的是原生應用內嵌瀏覽器控制元件 WebView(iOS 為 UIWebView 或 WKWebView,Android 為 WebView)的方式進行 HTML5 頁面渲染,並定義 HTML5 與原生程式碼互動協議,將部分原生系統能力暴露給 HTML5,從而擴充套件 HTML5 的邊界。這類互動協議,就是我們通常說的 JS Bridge(橋)。 這種開發模式既有原生應用程式碼又有 Web 應用程式碼,因此又被稱為 Hybrid 開發模式。

Flutter核心技術與實戰

  • 泛 Web 容器時代 泛 Web 容器時代的解決方案優化了 Web 容器時代的載入、解析和渲染這三大過程,把影響它們獨立執行的 Web 標準進行了裁剪,以相對簡單的方式支援了構建移動端頁面必要的 Web 標準(如 Flexbox 等),也保證了便捷的前端開發體驗;同時,這個時代的解決方案基本上完全放棄了瀏覽器控制元件渲染,而是採用原生自帶的 UI 元件實現代替了核心的渲染引擎,僅保持必要的基本控制元件渲染能力,從而使得渲染過程更加簡化,也保證了良好的渲染效能。

Flutter核心技術與實戰

  • 自繪引擎時代 泛 Web 容器時代使用原生控制元件承載介面渲染,固然解決了不少效能問題,但同時也帶來了新的問題。拋開框架本身需要處理大量平臺相關的邏輯外,隨著系統版本變化和 API 的變化,我們還需要處理不同平臺的原生控制元件渲染能力差異,修復各類奇奇怪怪的 Bug。

Flutter 則開闢了一種全新的思路,即從頭到尾重寫一套跨平臺的 UI 框架,包括渲染邏輯,甚至是開發語言。

渲染引擎依靠跨平臺的 Skia 圖形庫來實現,Skia 引擎會將使用 Dart 構建的抽象的檢視結構資料加工成 GPU 資料,交由 OpenGL 最終提供給 GPU 渲染,至此完成渲染閉環,因此可以在最大程度上保證一款應用在不同平臺、不同裝置上的體驗一致性。

而開發語言選用的是同時支援 JIT(Just-in-Time,即時編譯)和 AOT(Ahead-of-Time,預編譯)的 Dart,不僅保證了開發效率,更提升了執行效率(比使用 JavaScript 開發的泛 Web 容器方案要高得多)。

Flutter核心技術與實戰

相關文章