一. 認(rèn)識(shí)Flutter
1.1. 什么是Flutter
簡(jiǎn)單翻譯一下:
Flutter是谷歌主導(dǎo)研發(fā)的一個(gè)UI工具包蛾派,可以利用它固蛾,使用非常簡(jiǎn)潔的代碼開發(fā)出漂亮的、原生的應(yīng)用程序,無論是在移動(dòng)端潜沦、Web端還是桌面端。
嗯绪氛,加入個(gè)人理解:
Flutter就是一個(gè)UI開發(fā)工具包唆鸡,可以開發(fā)各個(gè)平臺(tái),但是目前最活躍的地方依然 移動(dòng)平臺(tái)枣察,雖然他也支持Web争占、桌面,甚至也將是Google Fuchsia[4]下開發(fā)應(yīng)用的主要工具序目。
但是現(xiàn)在臂痕,它只是活躍于移動(dòng)端。
那么猿涨,目前移動(dòng)平臺(tái)主要有哪些呢刻蟹?沒錯(cuò),iOS嘿辟、Android舆瘪!
于是片效,我們可以簡(jiǎn)單概述一下Flutter:
Flutter目前被應(yīng)用最廣泛的就是作為iOS、Android跨平臺(tái)解決方案英古,而且可以說是目前最優(yōu)秀的跨平臺(tái)解決方案淀衣。
它不僅僅性能優(yōu)越,而且開發(fā)非常高效召调!
為什么需要這樣一種跨平臺(tái)解決方案呢膨桥?
待會(huì)兒我會(huì)講到移動(dòng)端開發(fā)的歷史(各端獨(dú)立開發(fā)到跨平臺(tái)開發(fā)的出現(xiàn))以及在整個(gè)歷史進(jìn)程中出現(xiàn)的各個(gè)痛點(diǎn),直到Flutter的出現(xiàn)唠叛。
1.2. Flutter的特點(diǎn)
Google公司在國內(nèi)做過很多宣講只嚣,其中多次提到Flutter的幾個(gè)特點(diǎn):美觀、快速艺沼、高效册舞、開放。
這部分了解即可障般,后面學(xué)習(xí)過程中调鲸,慢慢體會(huì)。
美觀
使用Flutter內(nèi)置美麗的Material Design和Cupertinowidget(什么是widget挽荡,不著急)藐石、豐富的motion API、平滑而自然的滑動(dòng)效果和平臺(tái)感知定拟,為您的用戶帶來全新體驗(yàn)于微。
當(dāng)然,在我們真正學(xué)會(huì)使用它開發(fā)之前青自,這些東西不能深刻的體會(huì)角雷,后面大家會(huì)慢慢體會(huì)到的
快速
后面有專門講解為什么性能這么高,先做一個(gè)了解即可
Flutter 的 UI 渲染性能很好性穿。在生產(chǎn)環(huán)境下勺三,F(xiàn)lutter 將代碼編譯成機(jī)器碼執(zhí)行,并充分利用 GPU 的圖形加速能力需曾,因此使用 Flutter 開發(fā)的移動(dòng)應(yīng)用即使在低配手機(jī)上也能實(shí)現(xiàn)每秒 60 幀的 UI 渲染速度吗坚。
Flutter 引擎使用 C++ 編寫,包括高效的 Skia 2D 渲染引擎呆万,Dart 運(yùn)行時(shí)和文本渲染庫商源。
這個(gè)引擎使得 Flutter 框架可以自由、靈活谋减、高效地繪制 UI 組件牡彻。而應(yīng)用開發(fā)者則可以用 Flutter 框架來輕松實(shí)現(xiàn)各種設(shè)計(jì)語言和動(dòng)畫效果。
高效
對(duì)開發(fā)者來說,使用 Flutter 開發(fā)應(yīng)用十分高效庄吼。
Flutter 廣受好評(píng)的 Hot Reload (熱重載) 功能可以在 1 秒內(nèi)實(shí)現(xiàn)代碼到 UI 的更新缎除,使得開發(fā)操作周期被大幅縮短。
另外总寻,熱重載能夠在執(zhí)行的時(shí)候保留應(yīng)用的當(dāng)前狀態(tài) (即 Stateful)器罐,比如您可能在修改一個(gè)導(dǎo)航結(jié)構(gòu)里的子頁面,保留狀態(tài)的熱重載可以讓您不需要重新從起始頁一路點(diǎn)擊回到這個(gè)子頁面渐行,而是在代碼修改完成后即刻看到結(jié)果轰坊。
開放
Flutter 是開放的,它是一個(gè)完全開源的項(xiàng)目祟印。全球的開發(fā)者都可以免費(fèi)使用和拓展 Flutter 的源代碼肴沫,并為 Flutter 的生態(tài)和文檔作貢獻(xiàn)。我們已經(jīng)看到許多中國開發(fā)者(比如閑魚開發(fā)團(tuán)隊(duì))活躍在社區(qū)中蕴忆,并為 Flutter 做出了很多貢獻(xiàn)颤芬。
二. 跨平臺(tái)歷史
2.1. 平臺(tái)獨(dú)立開發(fā)
目前移動(dòng)端有兩大系統(tǒng):iOS和Android
很多公司為了擴(kuò)散自己的產(chǎn)品,都需要在兩大系統(tǒng)上跑自己的應(yīng)用程序App
意味著Android系統(tǒng)上需要一個(gè)Android版本的App
意味著iOS系統(tǒng)上需要一個(gè)iOS版本的App
但是他們的開發(fā)方式完全不同D跷摹!夺艰!
iOS系統(tǒng)
最初芋哭,如果希望在其上開發(fā)應(yīng)用程序,所采用的語言是Objective-C(沒用過的人會(huì)被他的語法嚇到)郁副。
2014年减牺,蘋果在WWDC大會(huì)上發(fā)布了新的語言Swift,Swift更加現(xiàn)代化存谎,也更加接近于其他語言拔疚,被認(rèn)為是Objective-C的替代品(但是到現(xiàn)在都還沒有替代,兩個(gè)都在用)既荚。
也就是現(xiàn)在開發(fā)iOS系統(tǒng)上的應(yīng)用需要掌握兩門語言:Objective-C和Swift
Android系統(tǒng)
最初稚失,如果希望在其上開發(fā)應(yīng)用程序,所采用的語言是Java
2011年JetBrains推出Kotlin項(xiàng)目恰聘,在Google I/O2017中句各,Google宣布在Android上為Kotlin提供最佳支持
也就是現(xiàn)在開發(fā)Android系統(tǒng)上的應(yīng)用需要掌握兩門語言:Java和Kotlin
通常在一個(gè)公司,很難讓一個(gè)人同時(shí)去勝任iOS開發(fā)和Android開發(fā)兩個(gè)崗位晴叨,所以在一家公司可能就需要同時(shí)有iOS組和Android組分別針對(duì)不同的系統(tǒng)進(jìn)行開發(fā)凿宾。
但是,對(duì)于一家小公司來說兼蕊,這樣的成本是非常高的初厚。
在很長(zhǎng)一段時(shí)間內(nèi),大家都在需求一種移動(dòng)端的跨平臺(tái)解決方案孙技,希望可以通過一套代碼開發(fā)出可以同時(shí)運(yùn)行在iOS和Android兩個(gè)系統(tǒng)上的應(yīng)用程序
2.2. 跨平臺(tái)解決方案
基于 JavaScript 和 WebView的跨平臺(tái)
最早出現(xiàn)的跨平臺(tái)框架是基于 JavaScript 和 WebView产禾,代表框架有PhoneGap排作,Apache Cordova,Ionic 等等下愈。
主要是通過HTML來構(gòu)建自己的界面纽绍,再將其顯示在各個(gè)平臺(tái)的WebView中。
但是它默認(rèn)是不能調(diào)用本地的一些服務(wù)的(比如相機(jī)势似、藍(lán)牙等)拌夏,所以需要通過JavaScript進(jìn)行橋接調(diào)用Native的一些代碼來完成某些功能。
但是履因,它本身的體驗(yàn)并不理想障簿,而且開發(fā)過程中的坑非常多。
備受歡迎的React Native
在尋求最佳跨平臺(tái)解決方案的過程中栅迄,無疑React Native 是之前最優(yōu)秀的一個(gè)站故。
React Native (簡(jiǎn)稱RN)是Facebook于2015年4月開源的跨平臺(tái)移動(dòng)應(yīng)用開發(fā)框架,是Facebook早先開源的JS框架 React 在原生移動(dòng)應(yīng)用平臺(tái)的衍生產(chǎn)物毅舆,目前支持iOS和安卓?jī)纱笃脚_(tái)西篓。
RN使用JavaScript語言,類似于HTML的JSX憋活,以及CSS來開發(fā)移動(dòng)應(yīng)用岂津,因此熟悉Web前端開發(fā)的技術(shù)人員只需很少的學(xué)習(xí)就可以進(jìn)入移動(dòng)應(yīng)用開發(fā)領(lǐng)域。
并且在保留基本渲染能力的基礎(chǔ)上悦即,用原生自帶的 UI 組件實(shí)現(xiàn)代替了核心的渲染引擎吮成,從而保證了良好的渲染性能。
但是辜梳,由于RN的本質(zhì)是通過JavaScript VM調(diào)用遠(yuǎn)程接口粱甫,通信相對(duì)比較低效,而且框架本身不負(fù)責(zé)渲染作瞄,而是是間接通過原生進(jìn)行渲染的茶宵。
還有一個(gè)就是在進(jìn)行iOS和Android適配的過程中,還要求開發(fā)者對(duì)兩大系統(tǒng)本身有所熟悉才行宗挥。
所在在RN上做出非常多貢獻(xiàn)的Airbnb之前就宣布放棄RN节预,而轉(zhuǎn)向Native進(jìn)行開發(fā)。
可能是終極的解決方案: Flutter
從Flutter出現(xiàn)到現(xiàn)在属韧,我個(gè)人就一直非嘲材猓看好,因?yàn)樗赡懿攀俏覀兒芫靡詠硭诖目缙脚_(tái)的終極解決方案宵喂。
我們直接看下面這幅圖來對(duì)比flutter - native - rn的區(qū)別
Flutter利用Skia繪圖引擎糠赦,直接通過CPU、GPU進(jìn)行繪制,不需要依賴任何原生的控件(后面有原理講解)
Android操作系統(tǒng)中拙泽,我們編寫的原生控件實(shí)際上也是依賴于Skia進(jìn)行繪制淌山,所以flutter在某些Android操作系統(tǒng)上甚至還要高于原生(因?yàn)樵鶤ndroid中的Skia必須隨著操作系統(tǒng)進(jìn)行更新,而Flutter SDK中總是保持最新的)
而類似于RN的框架顾瞻,必須通過某些橋接的方式先轉(zhuǎn)成原生進(jìn)行調(diào)用泼疑,之后再進(jìn)行渲染。
具體Flutter如何實(shí)現(xiàn)接近于原生的高性能的荷荤,下一個(gè)章節(jié)我們具體分析退渗。
三. Flutter繪制原理
這個(gè)章節(jié)設(shè)計(jì)到一些圖形繪制的原理,對(duì)于某些沒有基礎(chǔ)的同學(xué)可能會(huì)有一些困難蕴纳,這個(gè)沒有關(guān)系会油,并不影響后續(xù)的學(xué)習(xí)。
3.1. Flutter渲染本質(zhì)
問題:一個(gè)圖像到底是如何顯示到屏幕上的呢古毛?
首先翻翩,你需要知道,我們?cè)谄聊簧峡梢钥吹降乃袃?nèi)容都是計(jì)算機(jī)繪制出來的圖像稻薇,無論是視頻還是GIF圖片嫂冻,還是操作系統(tǒng)給我們看到的圖形化界面中的畫面,都是圖像塞椎。
我們將它分解出來桨仿,就會(huì)發(fā)現(xiàn)它是很多張圖片連續(xù)播放所看到的畫面
但是我們?yōu)槭裁茨芸吹筋愃朴趧?dòng)畫的效果呢?
這是因?yàn)樗シ诺乃俣确浅忱屑?斓徘茫芯勘砻鳎?br>
當(dāng)圖片連續(xù)播放的頻率超過16幀(16張圖片)暇昂,人眼就會(huì)感覺非常流暢莺戒,當(dāng)少于16幀時(shí),會(huì)感覺到卡頓
所以我們平時(shí)看到的電影急波,通常都是24幀或者30幀的(李安之前拍攝120幀的電影从铲,目的就是讓圖片間隔更小,畫面更加的流暢)
我們說回到電腦澄暮、手機(jī)屏幕的顯示
事實(shí)上顯示器就是以固定的頻率顯示圖像的名段,比如 iPhone的 60Hz、iPad Pro的 120Hz泣懊。
一幀圖像繪制完畢后準(zhǔn)備繪制下一幀時(shí)伸辟,顯示器會(huì)發(fā)出一個(gè)垂直同步信號(hào)(VSync),所以 60Hz的屏幕就會(huì)一秒內(nèi)發(fā)出 60次這樣的信號(hào)馍刮。
在計(jì)算機(jī)系統(tǒng)中信夫,CPU、GPU和顯示器以一種特定的方式協(xié)作:
CPU將計(jì)算好的顯示內(nèi)容提交給 GPU;
GPU渲染后放入幀緩沖區(qū)静稻;
視頻控制器按照 VSync信號(hào)從幀緩沖區(qū)取幀數(shù)據(jù)傳遞給顯示器顯示警没;
當(dāng)然,Android振湾、iOS 的 UI 渲染過程是如此杀迹,F(xiàn)lutter 也是如此,在整個(gè) Flutter 架構(gòu)中押搪,F(xiàn)lutter 只關(guān)心向 GPU 提供顯示數(shù)據(jù)树酪,并不關(guān)心顯示器、視頻控制器以及 GPU 是如何工作的嵌言。
GPU將信號(hào)同步到 UI 線程
UI 線程用Dart來構(gòu)建圖層樹
圖層樹在GPU 線程進(jìn)行合成
合成后的視圖數(shù)據(jù)提供給Skia 引擎
Skia 引擎通過OpenGL 或者 Vulkan將顯示內(nèi)容提供給GPU
這也是flutter區(qū)別于React Native的本質(zhì)區(qū)別:
React Native 之類的框架嗅回,只是通過 JavaScript 虛擬機(jī)擴(kuò)展調(diào)用系統(tǒng)組件,由 Android 和 iOS 系統(tǒng)進(jìn)行組件的渲染摧茴;
Flutter 是自己完成了組件渲染的閉環(huán)绵载。
3.2. Dart語言優(yōu)勢(shì)
Flutter為什么要選擇Dart作為開發(fā)語言?
有一種半開玩笑的說法: 因?yàn)镈art團(tuán)隊(duì)就在Flutter團(tuán)隊(duì)的旁邊苛白,溝通起來非常方便(是玩笑娃豹,也是事實(shí),dart語言本身針對(duì)Flutter進(jìn)行過很多次的優(yōu)化)
早期的 Flutter 團(tuán)隊(duì)評(píng)估了十多種語言购裙,并選擇了 Dart懂版,因?yàn)樗纤麄儤?gòu)建用戶界面的方式。
其實(shí)針對(duì)于前端開發(fā)者來說躏率,選擇JavaScript看起來更合適躯畴,因?yàn)榇蠹业娜腴T成本會(huì)更低,會(huì)有更多人選擇學(xué)習(xí)和使用Flutter薇芝。
但是Flutter團(tuán)隊(duì)從一開始就決定蓬抄,不將就!:坏健嚷缭!
Dart 是 AOT(Ahead Of Time)編譯的,編譯成快速耍贾、可預(yù)測(cè)的本地代碼阅爽,使 Flutter 幾乎都可以使用 Dart 編寫。這不僅使 Flutter 變得更快荐开,而且?guī)缀跛械臇|西(包括所有的小部件)都可以定制付翁。
Dart 也可以 JIT(Just In Time)編譯,開發(fā)周期異郴翁快百侧,工作流顛覆常規(guī)(包括 Flutter 流行的亞秒級(jí)有狀態(tài)熱重載)着帽。
Dart 可以更輕松地創(chuàng)建以 60fps 運(yùn)行的流暢動(dòng)畫和轉(zhuǎn)場(chǎng)。Dart 可以在沒有鎖的情況下進(jìn)行對(duì)象分配和垃圾回收移层。就像 JavaScript 一樣仍翰,Dart 避免了搶占式調(diào)度和共享內(nèi)存(因而也不需要鎖)。由于 Flutter 應(yīng)用程序被編譯為本地代碼观话,因此它們不需要在領(lǐng)域之間建立緩慢的橋梁(例如予借,JavaScript 到本地代碼)。它的啟動(dòng)速度也快得多频蛔。
Dart 使 Flutter 不需要單獨(dú)的聲明式布局語言灵迫,如 JSX 或 XML,或單獨(dú)的可視化界面構(gòu)建器晦溪,因?yàn)?Dart 的聲明式編程布局易于閱讀和可視化瀑粥。所有的布局使用一種語言,聚集在一處三圆,F(xiàn)lutter 很容易提供高級(jí)工具狞换,使布局更簡(jiǎn)單。
開發(fā)人員發(fā)現(xiàn) Dart 特別容易學(xué)習(xí)舟肉,因?yàn)樗哂徐o態(tài)和動(dòng)態(tài)語言用戶都熟悉的特性修噪。
并非所有這些功能都是 Dart 獨(dú)有的,但它們的組合卻恰到好處路媚,使 Dart 在實(shí)現(xiàn) Flutter 方面獨(dú)一無二黄琼。因此,沒有 Dart整慎,很難想象 Flutter 像現(xiàn)在這樣強(qiáng)大脏款。
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)是一個(gè)由C++編寫的開源圖形庫丈氓,能在低端設(shè)備如手機(jī)上呈現(xiàn)高質(zhì)量的2D圖形周循,最初由Skia公司開發(fā)强法,后被Google收購,應(yīng)用于Android湾笛、Google Chrome饮怯、Chrome OS等等當(dāng)中。
目前嚎研,Skia 已然是 Android 官方的圖像渲染引擎了蓖墅,因此 Flutter Android SDK 無需內(nèi)嵌 Skia 引擎就可以獲得天然的 Skia 支持库倘;
而對(duì)于 iOS 平臺(tái)來說,由于 Skia 是跨平臺(tái)的论矾,因此它作為 Flutter iOS 渲染引擎被嵌入到 Flutter 的 iOS SDK 中教翩,替代了 iOS 閉源的 Core Graphics/Core Animation/Core Text,這也正是 Flutter iOS SDK 打包的 App 包體積比 Android 要大一些的原因贪壳。
底層渲染能力統(tǒng)一了饱亿,上層開發(fā)接口和功能體驗(yàn)也就隨即統(tǒng)一了,開發(fā)者再也不用操心平臺(tái)相關(guān)的渲染特性了闰靴。也就是說彪笼,Skia 保證了同一套代碼調(diào)用在 Android 和 iOS 平臺(tái)上的渲染效果是完全一致的。
四. 如何學(xué)習(xí)flutter
4.1. 大前端學(xué)不動(dòng)了
很多人看到Google的flutter框架的時(shí)候蚂且,第一反應(yīng)就是:別出新東西了配猫,實(shí)在學(xué)不動(dòng)了。
但是作為大前端開發(fā)者就是這樣杏死,各種折騰:
客戶端開發(fā)者:從Android到iOS泵肄,或者從iOS到Android,到RN淑翼,甚至現(xiàn)在越來越多的客戶端開發(fā)者接觸前端相關(guān)知識(shí)(Vue凡伊、React、Angular窒舟、小程序)
前端開發(fā)者:從jQuery到AngularJS系忙,到三大框架并行:Vue、React惠豺、Angular银还,還有小程序,甚至現(xiàn)在也要接觸客戶端開發(fā)(比如RN洁墙、Flutter)
大前端開發(fā)就是蛹疯,不像服務(wù)器一樣可能幾年甚至幾十年還是那一套的東西,新技術(shù)會(huì)層出不窮热监。
但是每一樣技術(shù)的出現(xiàn)都會(huì)讓驚喜捺弦,因?yàn)樗厝皇墙鉀Q了之前技術(shù)的某一個(gè)痛點(diǎn)的,所以我們要學(xué)會(huì)擁抱這種變化孝扛。
并且很多知識(shí)在學(xué)習(xí)的過程中列吼,你會(huì)發(fā)現(xiàn)他們都是相同的,并不是說都要從頭再來苦始,最重要的是建立屬于自己的知識(shí)體系寞钥。
4.2. flutter學(xué)得會(huì)嗎?
很多人對(duì)于學(xué)習(xí)望而卻步陌选,主要是基于兩點(diǎn)考慮:
學(xué)習(xí)一門全新的語言:dart理郑,也就是你必須從你原來熟悉的語言JavaScript或Swift或Java或其他轉(zhuǎn)向這門全新的語言蹄溉。
flutter是全新的跨平臺(tái)技術(shù),意味著自己需要去學(xué)習(xí)很多新的內(nèi)容:開發(fā)模式、框架原理、底層原理渲染機(jī)制等等
dart語言并不復(fù)雜批糟,而且非常現(xiàn)代化
首先餐弱,所有編程語言都是大同小異,你花兩天的時(shí)間去練習(xí)一定可以快速掌握它囱晴。(我個(gè)人一直認(rèn)為一個(gè)開發(fā)者不可能在整個(gè)開發(fā)生涯只會(huì)一種編程語言膏蚓,不現(xiàn)實(shí)!)
其次畸写,dart語言幾乎集結(jié)了現(xiàn)代語言所有好用的特性驮瞧,并不復(fù)雜(后面我們慢慢來學(xué))
flutter并沒有非常多創(chuàng)新的概念:
flutter從其他框架中借鑒了非常多設(shè)計(jì)思想:框架原理、底層渲染機(jī)制枯芬、事件處理方式都大同小異论笔。
聲明式編程方式、組件化開發(fā)也是現(xiàn)代框架都有的特性千所,比如Vue狂魔、React。
后續(xù)的學(xué)習(xí)過程中淫痰,我也會(huì)循序漸進(jìn)最楷,帶著大家一點(diǎn)點(diǎn)來學(xué)習(xí)。