一. 認識Flutter
1.1. 什么是Flutter
簡單翻譯一下:
Flutter是谷歌主導研發(fā)的一個UI工具包,可以利用它,使用非常簡潔的代碼開發(fā)出漂亮的、原生的應用程序,無論是在移動端、Web端還是桌面端。
嗯,加入個人理解:
Flutter就是一個UI開發(fā)工具包,可以開發(fā)各個平臺,但是目前最活躍的地方依然 移動平臺,雖然他也支持Web、桌面,甚至也將是Google Fuchsia[4]下開發(fā)應用的主要工具。
但是現(xiàn)在,它只是活躍于移動端。
那么,目前移動平臺主要有哪些呢?沒錯,iOS、Android!
于是,我們可以簡單概述一下Flutter:
Flutter目前被應用最廣泛的就是作為iOS、Android跨平臺解決方案,而且可以說是目前最優(yōu)秀的跨平臺解決方案。
它不僅僅性能優(yōu)越,而且開發(fā)非常高效!
為什么需要這樣一種跨平臺解決方案呢?
待會兒我會講到移動端開發(fā)的歷史(各端獨立開發(fā)到跨平臺開發(fā)的出現(xiàn))以及在整個歷史進程中出現(xiàn)的各個痛點,直到Flutter的出現(xiàn)。
1.2. Flutter的特點
Google公司在國內(nèi)做過很多宣講,其中多次提到Flutter的幾個特點:美觀、快速、高效、開放。
這部分了解即可,后面學習過程中,慢慢體會。
美觀
使用Flutter內(nèi)置美麗的Material Design和Cupertinowidget(什么是widget,不著急)、豐富的motion API、平滑而自然的滑動效果和平臺感知,為您的用戶帶來全新體驗。
當然,在我們真正學會使用它開發(fā)之前,這些東西不能深刻的體會,后面大家會慢慢體會到的
快速
后面有專門講解為什么性能這么高,先做一個了解即可
Flutter 的 UI 渲染性能很好。在生產(chǎn)環(huán)境下,F(xiàn)lutter 將代碼編譯成機器碼執(zhí)行,并充分利用 GPU 的圖形加速能力,因此使用 Flutter 開發(fā)的移動應用即使在低配手機上也能實現(xiàn)每秒 60 幀的 UI 渲染速度。
Flutter 引擎使用 C++ 編寫,包括高效的 Skia 2D 渲染引擎,Dart 運行時和文本渲染庫。
這個引擎使得 Flutter 框架可以自由、靈活、高效地繪制 UI 組件。而應用開發(fā)者則可以用 Flutter 框架來輕松實現(xiàn)各種設(shè)計語言和動畫效果。

高效
對開發(fā)者來說,使用 Flutter 開發(fā)應用十分高效。
Flutter 廣受好評的 Hot Reload (熱重載) 功能可以在 1 秒內(nèi)實現(xiàn)代碼到 UI 的更新,使得開發(fā)操作周期被大幅縮短。
另外,熱重載能夠在執(zhí)行的時候保留應用的當前狀態(tài) (即 Stateful),比如您可能在修改一個導航結(jié)構(gòu)里的子頁面,保留狀態(tài)的熱重載可以讓您不需要重新從起始頁一路點擊回到這個子頁面,而是在代碼修改完成后即刻看到結(jié)果。

開放
Flutter 是開放的,它是一個完全開源的項目。全球的開發(fā)者都可以免費使用和拓展 Flutter 的源代碼,并為 Flutter 的生態(tài)和文檔作貢獻。我們已經(jīng)看到許多中國開發(fā)者(比如閑魚開發(fā)團隊)活躍在社區(qū)中,并為 Flutter 做出了很多貢獻。

二. 跨平臺歷史
2.1. 平臺獨立開發(fā)
目前移動端有兩大系統(tǒng):iOS和Android
很多公司為了擴散自己的產(chǎn)品,都需要在兩大系統(tǒng)上跑自己的應用程序App
意味著Android系統(tǒng)上需要一個Android版本的App
意味著iOS系統(tǒng)上需要一個iOS版本的App
但是他們的開發(fā)方式完全不同?。。?br>
iOS系統(tǒng)
最初,如果希望在其上開發(fā)應用程序,所采用的語言是Objective-C(沒用過的人會被他的語法嚇到)。
2014年,蘋果在WWDC大會上發(fā)布了新的語言Swift,Swift更加現(xiàn)代化,也更加接近于其他語言,被認為是Objective-C的替代品(但是到現(xiàn)在都還沒有替代,兩個都在用)。
也就是現(xiàn)在開發(fā)iOS系統(tǒng)上的應用需要掌握兩門語言:Objective-C和Swift
Android系統(tǒng)
最初,如果希望在其上開發(fā)應用程序,所采用的語言是Java
2011年JetBrains推出Kotlin項目,在Google I/O2017中,Google宣布在Android上為Kotlin提供最佳支持
也就是現(xiàn)在開發(fā)Android系統(tǒng)上的應用需要掌握兩門語言:Java和Kotlin
通常在一個公司,很難讓一個人同時去勝任iOS開發(fā)和Android開發(fā)兩個崗位,所以在一家公司可能就需要同時有iOS組和Android組分別針對不同的系統(tǒng)進行開發(fā)。
但是,對于一家小公司來說,這樣的成本是非常高的。
在很長一段時間內(nèi),大家都在需求一種移動端的跨平臺解決方案,希望可以通過一套代碼開發(fā)出可以同時運行在iOS和Android兩個系統(tǒng)上的應用程序
2.2. 跨平臺解決方案
基于 JavaScript 和 WebView的跨平臺
最早出現(xiàn)的跨平臺框架是基于 JavaScript 和 WebView,代表框架有PhoneGap,Apache Cordova,Ionic 等等。
主要是通過HTML來構(gòu)建自己的界面,再將其顯示在各個平臺的WebView中。
但是它默認是不能調(diào)用本地的一些服務(wù)的(比如相機、藍牙等),所以需要通過JavaScript進行橋接調(diào)用Native的一些代碼來完成某些功能。
但是,它本身的體驗并不理想,而且開發(fā)過程中的坑非常多。

備受歡迎的React Native
在尋求最佳跨平臺解決方案的過程中,無疑React Native 是之前最優(yōu)秀的一個。
React Native (簡稱RN)是Facebook于2015年4月開源的跨平臺移動應用開發(fā)框架,是Facebook早先開源的JS框架 React 在原生移動應用平臺的衍生產(chǎn)物,目前支持iOS和安卓兩大平臺。
RN使用JavaScript語言,類似于HTML的JSX,以及CSS來開發(fā)移動應用,因此熟悉Web前端開發(fā)的技術(shù)人員只需很少的學習就可以進入移動應用開發(fā)領(lǐng)域。
并且在保留基本渲染能力的基礎(chǔ)上,用原生自帶的 UI 組件實現(xiàn)代替了核心的渲染引擎,從而保證了良好的渲染性能。
但是,由于RN的本質(zhì)是通過JavaScript VM調(diào)用遠程接口,通信相對比較低效,而且框架本身不負責渲染,而是是間接通過原生進行渲染的。
還有一個就是在進行iOS和Android適配的過程中,還要求開發(fā)者對兩大系統(tǒng)本身有所熟悉才行。
所在在RN上做出非常多貢獻的Airbnb之前就宣布放棄RN,而轉(zhuǎn)向Native進行開發(fā)。

可能是終極的解決方案: Flutter
從Flutter出現(xiàn)到現(xiàn)在,我個人就一直非??春茫驗樗赡懿攀俏覀兒芫靡詠硭诖目缙脚_的終極解決方案。
我們直接看下面這幅圖來對比flutter - native - rn的區(qū)別
Flutter利用Skia繪圖引擎,直接通過CPU、GPU進行繪制,不需要依賴任何原生的控件(后面有原理講解)
Android操作系統(tǒng)中,我們編寫的原生控件實際上也是依賴于Skia進行繪制,所以flutter在某些Android操作系統(tǒng)上甚至還要高于原生(因為原生Android中的Skia必須隨著操作系統(tǒng)進行更新,而Flutter SDK中總是保持最新的)
而類似于RN的框架,必須通過某些橋接的方式先轉(zhuǎn)成原生進行調(diào)用,之后再進行渲染。
具體Flutter如何實現(xiàn)接近于原生的高性能的,下一個章節(jié)我們具體分析。

三. Flutter繪制原理
這個章節(jié)設(shè)計到一些圖形繪制的原理,對于某些沒有基礎(chǔ)的同學可能會有一些困難,這個沒有關(guān)系,并不影響后續(xù)的學習。
3.1. Flutter渲染本質(zhì)
問題:一個圖像到底是如何顯示到屏幕上的呢?
首先,你需要知道,我們在屏幕上可以看到的所有內(nèi)容都是計算機繪制出來的圖像,無論是視頻還是GIF圖片,還是操作系統(tǒng)給我們看到的圖形化界面中的畫面,都是圖像。
我們將它分解出來,就會發(fā)現(xiàn)它是很多張圖片連續(xù)播放所看到的畫面
但是我們?yōu)槭裁茨芸吹筋愃朴趧赢嫷男Ч兀?br>
這是因為它播放的速度非???,研究表明:
當圖片連續(xù)播放的頻率超過16幀(16張圖片),人眼就會感覺非常流暢,當少于16幀時,會感覺到卡頓
所以我們平時看到的電影,通常都是24幀或者30幀的(李安之前拍攝120幀的電影,目的就是讓圖片間隔更小,畫面更加的流暢)
我們說回到電腦、手機屏幕的顯示
事實上顯示器就是以固定的頻率顯示圖像的,比如 iPhone的 60Hz、iPad Pro的 120Hz。
一幀圖像繪制完畢后準備繪制下一幀時,顯示器會發(fā)出一個垂直同步信號(VSync),所以 60Hz的屏幕就會一秒內(nèi)發(fā)出 60次這樣的信號。

在計算機系統(tǒng)中,CPU、GPU和顯示器以一種特定的方式協(xié)作:
CPU將計算好的顯示內(nèi)容提交給 GPU;
GPU渲染后放入幀緩沖區(qū);
視頻控制器按照 VSync信號從幀緩沖區(qū)取幀數(shù)據(jù)傳遞給顯示器顯示;
當然,Android、iOS 的 UI 渲染過程是如此,F(xiàn)lutter 也是如此,在整個 Flutter 架構(gòu)中,F(xiàn)lutter 只關(guān)心向 GPU 提供顯示數(shù)據(jù),并不關(guān)心顯示器、視頻控制器以及 GPU 是如何工作的。

GPU將信號同步到 UI 線程
UI 線程用Dart來構(gòu)建圖層樹
圖層樹在GPU 線程進行合成
合成后的視圖數(shù)據(jù)提供給Skia 引擎
Skia 引擎通過OpenGL 或者 Vulkan將顯示內(nèi)容提供給GPU
這也是flutter區(qū)別于React Native的本質(zhì)區(qū)別:
React Native 之類的框架,只是通過 JavaScript 虛擬機擴展調(diào)用系統(tǒng)組件,由 Android 和 iOS 系統(tǒng)進行組件的渲染;
Flutter 是自己完成了組件渲染的閉環(huán)。
3.2. Dart語言優(yōu)勢
Flutter為什么要選擇Dart作為開發(fā)語言?
有一種半開玩笑的說法: 因為Dart團隊就在Flutter團隊的旁邊,溝通起來非常方便(是玩笑,也是事實,dart語言本身針對Flutter進行過很多次的優(yōu)化)
早期的 Flutter 團隊評估了十多種語言,并選擇了 Dart,因為它符合他們構(gòu)建用戶界面的方式。
其實針對于前端開發(fā)者來說,選擇JavaScript看起來更合適,因為大家的入門成本會更低,會有更多人選擇學習和使用Flutter。
但是Flutter團隊從一開始就決定,不將就?。。?br>
Dart 是 AOT(Ahead Of Time)編譯的,編譯成快速、可預測的本地代碼,使 Flutter 幾乎都可以使用 Dart 編寫。這不僅使 Flutter 變得更快,而且?guī)缀跛械臇|西(包括所有的小部件)都可以定制。
Dart 也可以 JIT(Just In Time)編譯,開發(fā)周期異???,工作流顛覆常規(guī)(包括 Flutter 流行的亞秒級有狀態(tài)熱重載)。
Dart 可以更輕松地創(chuàng)建以 60fps 運行的流暢動畫和轉(zhuǎn)場。Dart 可以在沒有鎖的情況下進行對象分配和垃圾回收。就像 JavaScript 一樣,Dart 避免了搶占式調(diào)度和共享內(nèi)存(因而也不需要鎖)。由于 Flutter 應用程序被編譯為本地代碼,因此它們不需要在領(lǐng)域之間建立緩慢的橋梁(例如,JavaScript 到本地代碼)。它的啟動速度也快得多。
Dart 使 Flutter 不需要單獨的聲明式布局語言,如 JSX 或 XML,或單獨的可視化界面構(gòu)建器,因為 Dart 的聲明式編程布局易于閱讀和可視化。所有的布局使用一種語言,聚集在一處,F(xiàn)lutter 很容易提供高級工具,使布局更簡單。
開發(fā)人員發(fā)現(xiàn) Dart 特別容易學習,因為它具有靜態(tài)和動態(tài)語言用戶都熟悉的特性。
并非所有這些功能都是 Dart 獨有的,但它們的組合卻恰到好處,使 Dart 在實現(xiàn) Flutter 方面獨一無二。因此,沒有 Dart,很難想象 Flutter 像現(xiàn)在這樣強大。
3.3. 渲染引擎skia
想要了解Flutter的本質(zhì),必須先了解它的底層圖像渲染引擎 Skia,前面提到了 Flutter只關(guān)心如何構(gòu)建視圖抽象結(jié)構(gòu),向 GPU提供視圖數(shù)據(jù)。Skia就是 Flutter向 GPU提供數(shù)據(jù)的途徑。
Skia全名Skia Graphics Library(SGL)是一個由C++編寫的開源圖形庫,能在低端設(shè)備如手機上呈現(xiàn)高質(zhì)量的2D圖形,最初由Skia公司開發(fā),后被Google收購,應用于Android、Google Chrome、Chrome OS等等當中。
目前,Skia 已然是 Android 官方的圖像渲染引擎了,因此 Flutter Android SDK 無需內(nèi)嵌 Skia 引擎就可以獲得天然的 Skia 支持;
而對于 iOS 平臺來說,由于 Skia 是跨平臺的,因此它作為 Flutter iOS 渲染引擎被嵌入到 Flutter 的 iOS SDK 中,替代了 iOS 閉源的 Core Graphics/Core Animation/Core Text,這也正是 Flutter iOS SDK 打包的 App 包體積比 Android 要大一些的原因。
底層渲染能力統(tǒng)一了,上層開發(fā)接口和功能體驗也就隨即統(tǒng)一了,開發(fā)者再也不用操心平臺相關(guān)的渲染特性了。也就是說,Skia 保證了同一套代碼調(diào)用在 Android 和 iOS 平臺上的渲染效果是完全一致的。

四. 如何學習flutter
4.1. 大前端學不動了
很多人看到Google的flutter框架的時候,第一反應就是:別出新東西了,實在學不動了。
但是作為大前端開發(fā)者就是這樣,各種折騰:
客戶端開發(fā)者:從Android到iOS,或者從iOS到Android,到RN,甚至現(xiàn)在越來越多的客戶端開發(fā)者接觸前端相關(guān)知識(Vue、React、Angular、小程序)
前端開發(fā)者:從jQuery到AngularJS,到三大框架并行:Vue、React、Angular,還有小程序,甚至現(xiàn)在也要接觸客戶端開發(fā)(比如RN、Flutter)
大前端開發(fā)就是,不像服務(wù)器一樣可能幾年甚至幾十年還是那一套的東西,新技術(shù)會層出不窮。
但是每一樣技術(shù)的出現(xiàn)都會讓驚喜,因為他必然是解決了之前技術(shù)的某一個痛點的,所以我們要學會擁抱這種變化。
并且很多知識在學習的過程中,你會發(fā)現(xiàn)他們都是相同的,并不是說都要從頭再來,最重要的是建立屬于自己的知識體系。
4.2. flutter學得會嗎?
很多人對于學習望而卻步,主要是基于兩點考慮:
學習一門全新的語言:dart,也就是你必須從你原來熟悉的語言JavaScript或Swift或Java或其他轉(zhuǎn)向這門全新的語言。
flutter是全新的跨平臺技術(shù),意味著自己需要去學習很多新的內(nèi)容:開發(fā)模式、框架原理、底層原理渲染機制等等
dart語言并不復雜,而且非?,F(xiàn)代化
首先,所有編程語言都是大同小異,你花兩天的時間去練習一定可以快速掌握它。(我個人一直認為一個開發(fā)者不可能在整個開發(fā)生涯只會一種編程語言,不現(xiàn)實?。?br>
其次,dart語言幾乎集結(jié)了現(xiàn)代語言所有好用的特性,并不復雜(后面我們慢慢來學)
flutter并沒有非常多創(chuàng)新的概念:
flutter從其他框架中借鑒了非常多設(shè)計思想:框架原理、底層渲染機制、事件處理方式都大同小異。
聲明式編程方式、組件化開發(fā)也是現(xiàn)代框架都有的特性,比如Vue、React。
后續(xù)的學習過程中,我也會循序漸進,帶著大家一點點來學習。