一. 認識Flutter1.1. 什麼是Flutter
先看看官方的解釋:
Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile[1], web[2], and desktop[3] from a single codebase.
簡單翻譯一下:
Flutter是谷歌主導研發的一個UI工具包,可以利用它,使用非常簡潔的程式碼開發出漂亮的、原生的應用程式,無論是在移動端、Web端還是桌面端。
嗯,加入個人理解:
Flutter就是一個UI開發工具包,可以開發各個平臺,但是目前最活躍的地方依然 移動平臺,雖然它也支援Web、桌面,甚至也將是Google Fuchsia[4]下開發應用的主要工具。
但是現在,它只是活躍於移動端。
那麼,目前移動平臺主要有哪些呢?沒錯,iOS、Android!
於是,我們可以簡單概述一下Flutter:
Flutter目前被應用最廣泛的就是作為iOS、Android跨平臺解決方案,而且可以說是目前最優秀的跨平臺解決方案。
它不僅僅效能優越,而且開發非常高效!
為什麼需要這樣一種跨平臺解決方案呢?
待會兒我會講到移動端開發的歷史(各端獨立開發到跨平臺開發的出現)以及在整個歷史程序中出現的各個痛點,直到Flutter的出現。
1.2. Flutter的特點Google公司在國內做過很多宣講,其中多次提到Flutter的幾個特點:美觀、快速、高效、開放。
這部分了解即可,後面學習過程中,慢慢體會。
美觀
使用Flutter內建美麗的Material Design和Cupertinowidget(什麼是widget,不著急)、豐富的motion API、平滑而自然的滑動效果和平臺感知,為您的使用者帶來全新體驗。
當然,在我們真正學會使用它開發之前,這些東西不能深刻的體會,後面大家會慢慢體會到的
快速
後面有專門講解為什麼效能這麼高,先做一個了解即可
Flutter 的 UI 渲染效能很好。在生產環境下,Flutter 將程式碼編譯成機器碼執行,並充分利用 GPU 的圖形加速能力,因此使用 Flutter 開發的移動應用即使在低配手機上也能實現每秒 60 幀的 UI 渲染速度。
Flutter 引擎使用 C++ 編寫,包括高效的 Skia 2D 渲染引擎,Dart 執行時和文字渲染庫。
這個引擎使得 Flutter 框架可以自由、靈活、高效地繪製 UI 元件。而應用開發者則可以用 Flutter 框架來輕鬆實現各種涉及語言和動畫效果。
高效
對開發者來說,使用 Flutter 開發應用十分高效。
Flutter 廣受好評的 Hot Reload (熱過載) 功能可以在 1 秒內實現程式碼到 UI 的更新,使得開發操作週期被大幅縮短。
另外,熱重在能夠在執行的時候保留應用的當前狀態 (即 Stateful),比如您可能在修改一個導航結構裡的子頁面,保留狀態的熱過載可以讓您不需要重新從起始頁一路點選回到這個子頁面,而是在程式碼修改完成後即可看到結果。
開放
Flutter 是開放的,它是一個完全開源的專案。全球的開發者都可以免費使用和拓展 Flutter 的原始碼,併為 Flutter 的生態和文件作貢獻。我們已經看到許多中國開發者(比如閒魚開發團隊)活躍在社群中,併為 Flutter 做出了很多貢獻。
二. 跨平臺歷史2.1. 平臺獨立開發目前移動端有兩大系統:iOS和Android
很多公司為了擴散自己的產品,都需要在兩大系統上跑自己的應用程式App
意味著Android系統上需要一個Android版本的App意味著iOS系統上需要一個iOS版本的App但是他們的開發方式完全不同!!!iOS系統
最初,如果希望在其上開發應用程式,所採用的語言是Objective-C(沒用過的人會被他的語法嚇到)。2014年,蘋果在WWDC大會上釋出了新的語言Swift,Swift更加現代化,也更加接近於其他語言,被認為是Objective-C的替代品(但是到現在都還沒有替代,兩個都在用)。也就是現在開發iOS系統上的應用需要掌握兩門語言:Objective-C和SwiftAndroid系統
最初,如果希望在其上開發應用程式,所採用的語言是Java2011年JetBrains推出Kotlin專案,在Google I/O2017中,Google宣佈在Android上為Kotlin提供最佳支援也就是現在開發Android系統上的應用需要掌握兩門語言:Java和Kotlin通常在一個公司,很難讓一個人同時去勝任iOS開發和Android開發兩個崗位,所以在一家公司可能就需要同時有iOS組和Android組分別針對不同的系統進行開發。
但是,對於一家小公司來說,這樣的成本是非常高的。
在很長一段時間內,大家都在尋求一種移動端的跨平臺解決方案,希望可以通過一套程式碼開發出可以同時執行在iOS和Android兩個系統上的應用程式
2.2. 跨平臺解決方案基於 JavaScript 和 WebView的跨平臺
最早出現的跨平臺框架是基於 JavaScript 和 WebView,代表框架有PhoneGap,Apache Cordova,Ionic 等等。
主要是通過HTML來構建自己的介面,再將其顯示在各個平臺的WebView中。
但是它預設是不能呼叫本地的一些服務的(比如相機、藍芽等),所以需要通過JavaScript進行橋接呼叫Native的一些程式碼來完成某些功能。
但是,它本身的體驗並不理想,而且開發過程中的坑非常多。
在尋求最佳跨平臺解決方案的過程中,無疑React Native 是之前最優秀的一個。
React Native (簡稱RN)是Facebook於2015年4月開源的跨平臺移動應用開發框架,是Facebook早先開源的JS框架 React 在原生移動應用平臺的衍生產物,目前支援iOS和安卓兩大平臺。
RN使用JavaScript語言,類似於HTML的JSX,以及CSS來開發移動應用,因此熟悉Web前端開發的技術人員只需很少的學習就可以進入移動應用開發領域。
並且在保留基本渲染能力的基礎上,用原生自帶的 UI 元件實現代替了核心的渲染引擎,從而保證了良好的渲染效能。
但是,由於RN的本質是通過JavaScript VM呼叫遠端介面,通訊相對比較低效,而且框架本身不負責渲染,而是是間接通過原生進行渲染的。
還有一個就是在進行iOS和Android適配的過程中,還要求開發者對兩大系統本身有所熟悉才行。
所在在RN上做出非常多貢獻的Airbnb之前就宣佈放棄RN,而轉向Native進行開發。
可能是終極的解決方案: Flutter
從Flutter出現到現在,我個人就一直非常看好,因為它可能才是我們很久以來所期待的跨平臺的終極解決方案。
我們直接看下面這幅圖來對比flutter - native - rn的區別
Flutter利用Skia繪圖引擎,直接通過CPU、GPU進行繪製,不需要依賴任何原生的控制元件(後面有原理講解)Android作業系統中,我們編寫的原生控制元件實際上也是依賴於Skia進行繪製,所以flutter在某些Android作業系統上甚至還要高於原生(因為原生Android中的Skia必須隨著作業系統進行更新,而Flutter SDK中總是保持最新的)而類似於RN的框架,必須通過某些橋接的方式先轉成原生進行呼叫,之後再進行渲染。具體Flutter如何實現接近於原生的高效能的,下一個章節我們具體分析。
三. Flutter繪製原理3.1. Flutter渲染本質這個章節涉及到一些圖形繪製的原理,對於某些沒有基礎的同學可能會有一些困難,這個沒有關係,並不影響後續的學習。
問題:一個影象到底是如何顯示到螢幕上的呢?
首先,你需要知道,我們在螢幕上可以看到的所有內容都是計算機繪製出來的影象,無論是視訊還是GIF圖片,還是作業系統給我們看到的圖形化介面中的畫面,都是影象。
比如下面的一個GIF圖片
我們將它分解出來,就會發現它是很多張圖片連續播放所看到的畫面
但是我們為什麼能看到類似於動畫的效果呢?
這是因為它播放的速度非常快,研究表明:
當圖片連續播放的頻率超過16幀(16張圖片),人眼就會感覺非常流暢,當少於16幀時,會感覺到卡頓所以我們平時看到的電影,通常都是24幀或者30幀的(李安之前拍攝120幀的電影,目的就是讓圖片間隔更小,畫面更加的流暢)我們說回到電腦、手機螢幕的顯示
事實上顯示器就是以固定的頻率顯示影象的,比如 iPhone的 60Hz、iPad Pro的 120Hz。
一幀影象繪製完畢後準備繪製下一幀時,顯示器會發出一個垂直同步訊號(VSync),所以 60Hz的螢幕就會一秒內發出 60次這樣的訊號。
img
在計算機系統中,CPU、GPU和顯示器以一種特定的方式協作:
CPU將計算好的顯示內容提交給 GPU;GPU渲染後放入幀緩衝區;視訊控制器按照 VSync訊號從幀緩衝區取幀資料傳遞給顯示器顯示;當然,Android、iOS 的 UI 渲染過程是如此,Flutter 也是如此,在整個 Flutter 架構中,Flutter 只關心向 GPU 提供顯示資料,並不關心顯示器、視訊控制器以及 GPU 是如何工作的。
flutter渲染機制
GPU將訊號同步到 UI 執行緒UI 執行緒用Dart來構建圖層樹圖層樹在GPU 執行緒進行合成合成後的檢視資料提供給Skia 引擎Skia 引擎通過OpenGL 或者 Vulkan將顯示內容提供給GPU這也是flutter區別於React Native的本質區別:
React Native 之類的框架,只是通過 JavaScript 虛擬機器擴充套件呼叫系統元件,由 Android 和 iOS 系統進行元件的渲染;Flutter 是自己完成了元件渲染的閉環。3.2. Dart語言優勢Flutter為什麼要選擇Dart作為開發語言?
有一種半開玩笑的說法: 因為Dart團隊就在Flutter團隊的旁邊,溝通起來非常方便(是玩笑,也是事實,dart語言本身針對Flutter進行過很多次的優化)
早期的 Flutter 團隊評估了十多種語言,並選擇了 Dart,因為它符合他們構建使用者介面的方式。
其實針對於前端開發者來說,選擇JavaScript看起來更合適,因為大家的入門成本會更低,會有更多人選擇學習和使用Flutter。
但是Flutter團隊從一開始就決定,不將就!!!
Dart 是 AOT(Ahead Of Time)編譯的,編譯成快速、可預測的原生代碼,使 Flutter 幾乎都可以使用 Dart 編寫。這不僅使 Flutter 變得更快,而且幾乎所有的東西(包括所有的小部件)都可以定製。Dart 也可以 JIT(Just In Time)編譯,開發週期異常快,工作流顛覆常規(包括 Flutter 流行的亞秒級有狀態熱過載)。Dart 可以更輕鬆地建立以 60fps 執行的流暢動畫和轉場。Dart 可以在沒有鎖的情況下進行物件分配和垃圾回收。就像 JavaScript 一樣,Dart 避免了搶佔式排程和共享記憶體(因而也不需要鎖)。由於 Flutter 應用程式被編譯為原生代碼,因此它們不需要在領域之間建立緩慢的橋樑(例如,JavaScript 到原生代碼)。它的啟動速度也快得多。Dart 使 Flutter 不需要單獨的宣告式佈局語言,如 JSX 或 XML,或單獨的視覺化介面構建器,因為 Dart 的宣告式程式設計佈局易於閱讀和視覺化。所有的佈局使用一種語言,聚集在一處,Flutter 很容易提供高階工具,使佈局更簡單。開發人員發現 Dart 特別容易學習,因為它具有靜態和動態語言使用者都熟悉的特性。並非所有這些功能都是 Dart 獨有的,但它們的組合卻恰到好處,使 Dart 在實現 Flutter 方面獨一無二。因此,沒有 Dart,很難想象 Flutter 像現在這樣強大。
3.3. 渲染引擎skia想要了解Flutter的本質,必須先了解它的底層影象渲染引擎 Skia,前面提到了 Flutter只關心如何構建檢視抽象結構,向 GPU提供檢視資料。Skia就是 Flutter向 GPU提供資料的途徑。
Skia全名Skia Graphics Library(SGL)是一個由C++編寫的開源圖形庫,能在低端裝置如手機上呈現高品質的2D圖形,最初由Skia公司開發,後被Google收購,應用於Android、Google Chrome、Chrome OS等等當中。
目前,Skia 已然是 Android 官方的影象渲染引擎了,因此 Flutter Android SDK 無需內嵌 Skia 引擎就可以獲得天然的 Skia 支援;
而對於 iOS 平臺來說,由於 Skia 是跨平臺的,因此它作為 Flutter iOS 渲染引擎被嵌入到 Flutter 的 iOS SDK 中,替代了 iOS 閉源的 Core Graphics/Core Animation/Core Text,這也正是 Flutter iOS SDK 打包的 App 包體積比 Android 要大一些的原因。
底層渲染能力統一了,上層開發介面和功能體驗也就隨即統一了,開發者再也不用操心平臺相關的渲染特性了。也就是說,Skia 保證了同一套程式碼呼叫在 Android 和 iOS 平臺上的渲染效果是完全一致的。
flutter架構
四. 如何學習flutter4.1. 大前端學不動了很多人看到Google的flutter框架的時候,第一反應就是:別出新東西了,實在學不動了。
但是作為大前端開發者就是這樣,各種折騰:
客戶端開發者:從Android到iOS,或者從iOS到Android,到RN,甚至現在越來越多的客戶端開發者接觸前端相關知識(Vue、React、Angular、小程式)前端開發者:從jQuery到AngularJS,到三大框架並行:Vue、React、Angular,還有小程式,甚至現在也要接觸客戶端開發(比如RN、Flutter)大前端開發就是,不像伺服器一樣可能幾年甚至幾十年還是那一套的東西,新技術會層出不窮。
但是每一樣技術的出現都會讓驚喜,因為它必然是解決了之前技術的某一個痛點的,所以我們要學會擁抱這種變化。
並且很多知識在學習的過程中,你會發現他們都是相同的,並不是說都要從頭再來,最重要的是建立屬於自己的知識體系。
4.2. flutter學得會嗎?很多人對於學習望而卻步,主要是基於兩點考慮:
學習一門全新的語言:dart,也就是你必須從你原來熟悉的語言JavaScript或Swift或Java或其他轉向這門全新的語言。flutter是全新的跨平臺技術,意味著自己需要去學習很多新的內容:開發模式、框架原理、底層原理渲染機制等等dart語言並不複雜,而且非常現代化
首先,所有程式語言都是大同小異,你花兩天的時間去練習一定可以快速掌握它。(我個人一直認為一個開發者不可能在整個開發生涯只會一種程式語言,不現實!)其次,dart語言幾乎集結了現代語言所有好用的特性,並不複雜(後面我們慢慢來學)flutter並沒有非常多創新的概念:
flutter從其他框架中借鑑了非常多設計思想:框架原理、底層渲染機制、事件處理方式都大同小異。宣告式程式設計方式、元件化開發也是現代框架獨有的特性,比如Vue、React。原文出處:/file/2020/04/30/20200430221807_203913.jpg