W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
Flutter 是 Google 推出并開(kāi)源的移動(dòng)應(yīng)用開(kāi)發(fā)框架,主打跨平臺(tái)、高保真、高性能。開(kāi)發(fā)者可以通過(guò) Dart 語(yǔ)言開(kāi)發(fā) App,一套代碼同時(shí)運(yùn)行在 iOS 和 Android 平臺(tái)。 Flutter 提供了豐富的組件、接口,開(kāi)發(fā)者可以很快地為 Flutter 添加 native 擴(kuò)展。同時(shí) Flutter還使用 Native 引擎渲染視圖,這無(wú)疑能為用戶提供良好的體驗(yàn)。
Flutter 與用于構(gòu)建移動(dòng)應(yīng)用程序的其它大多數(shù)框架不同,因?yàn)?Flutter 既不使用 WebView,也不使用操作系統(tǒng)的原生控件。 相反,F(xiàn)lutter 使用自己的高性能渲染引擎來(lái)繪制 widget。這樣不僅可以保證在 Android 和 iOS 上 UI 的一致性,而且也可以避免對(duì)原生控件依賴(lài)而帶來(lái)的限制及高昂的維護(hù)成本。
Flutter 使用 Skia 作為其 2D 渲染引擎,Skia 是 Google 的一個(gè) 2D 圖形處理函數(shù)庫(kù),包含字型、坐標(biāo)轉(zhuǎn)換,以及點(diǎn)陣圖都有高效能且簡(jiǎn)潔的表現(xiàn),Skia 是跨平臺(tái)的,并提供了非常友好的 API,目前 Google Chrome 瀏覽器和 Android 均采用 Skia 作為其繪圖引擎。
目前 Flutter 默認(rèn)支持 iOS、Android、Fuchsia(Google 新的自研操作系統(tǒng))三個(gè)移動(dòng)平臺(tái)。但 Flutter 亦可支持 Web 開(kāi)發(fā)(Flutter for web)和PC開(kāi)發(fā),本書(shū)的示例和介紹主要是基于 iOS 和 Android 平臺(tái)的,其它平臺(tái)讀者可以自行了解。
Flutter高性能主要靠?jī)牲c(diǎn)來(lái)保證,首先,F(xiàn)lutter APP 采用 Dart 語(yǔ)言開(kāi)發(fā)。Dart 在 JIT(即時(shí)編譯)模式下,速度與 JavaScript 基本持平。但是 Dart 支持 AOT,當(dāng)以 AOT 模式運(yùn)行時(shí),JavaScript 便遠(yuǎn)遠(yuǎn)追不上了。速度的提升對(duì)高幀率下的視圖數(shù)據(jù)計(jì)算很有幫助。其次,F(xiàn)lutter 使用自己的渲染引擎來(lái)繪制 UI,布局?jǐn)?shù)據(jù)等由Dart語(yǔ)言直接控制,所以在布局過(guò)程中不需要像RN那樣要在 JavaScript 和 Native 之間通信,這在一些滑動(dòng)和拖動(dòng)的場(chǎng)景下具有明顯優(yōu)勢(shì),因?yàn)樵诨瑒?dòng)和拖動(dòng)過(guò)程往往都會(huì)引起布局發(fā)生變化,所以 JavaScript 需要和 Native 之間不停的同步布局信息,這和在瀏覽器中要JavaScript頻繁操作DOM所帶來(lái)的問(wèn)題是相同的,都會(huì)帶來(lái)比較可觀的性能開(kāi)銷(xiāo)。
這是一個(gè)很有意思,但也很有爭(zhēng)議的問(wèn)題,在了解 Flutter 為什么選擇了 Dart 而不是 JavaScript 之前我們先來(lái)介紹兩個(gè)概念:JIT 和 AOT。
目前,程序主要有兩種運(yùn)行方式:靜態(tài)編譯與動(dòng)態(tài)解釋。靜態(tài)編譯的程序在執(zhí)行前全部被翻譯為機(jī)器碼,通常將這種類(lèi)型稱(chēng)為AOT (Ahead of time)即 “提前編譯”;而解釋執(zhí)行的則是一句一句邊翻譯邊運(yùn)行,通常將這種類(lèi)型稱(chēng)為JIT(Just-in-time)即“即時(shí)編譯”。AOT程序的典型代表是用C/C++開(kāi)發(fā)的應(yīng)用,它們必須在執(zhí)行前編譯成機(jī)器碼,而JIT的代表則非常多,如JavaScript、python等,事實(shí)上,所有腳本語(yǔ)言都支持JIT模式。但需要注意的是JIT和AOT指的是程序運(yùn)行方式,和編程語(yǔ)言并非強(qiáng)關(guān)聯(lián)的,有些語(yǔ)言既可以以JIT方式運(yùn)行也可以以AOT方式運(yùn)行,如Java、Python,它們可以在第一次執(zhí)行時(shí)編譯成中間字節(jié)碼、然后在之后執(zhí)行時(shí)可以直接執(zhí)行字節(jié)碼,也許有人會(huì)說(shuō),中間字節(jié)碼并非機(jī)器碼,在程序執(zhí)行時(shí)仍然需要?jiǎng)討B(tài)將字節(jié)碼轉(zhuǎn)為機(jī)器碼,是的,這沒(méi)有錯(cuò),不過(guò)通常我們區(qū)分是否為AOT的標(biāo)準(zhǔn)就是看代碼在執(zhí)行之前是否需要編譯,只要需要編譯,無(wú)論其編譯產(chǎn)物是字節(jié)碼還是機(jī)器碼,都屬于AOT。在此,讀者不必糾結(jié)于概念,概念就是為了傳達(dá)精神而發(fā)明的,只要讀者能夠理解其原理即可,得其神忘其形。
現(xiàn)在我們看看 Flutter 為什么選擇 Dart 語(yǔ)言?筆者根據(jù)官方解釋以及自己對(duì) Flutter 的理解總結(jié)了以下幾條(由于其它跨平臺(tái)框架都將 JavaScript 作為其開(kāi)發(fā)語(yǔ)言,所以主要將 Dart 和 JavaScript 做一個(gè)對(duì)比):
Dart 運(yùn)行時(shí)和編譯器支持 Flutter 的兩個(gè)關(guān)鍵特性的組合:
基于 JIT 的快速開(kāi)發(fā)周期:Flutter 在開(kāi)發(fā)階段采用,采用 JIT 模式,這樣就避免了每次改動(dòng)都要進(jìn)行編譯,極大的節(jié)省了開(kāi)發(fā)時(shí)間;
基于 AOT 的發(fā)布包: Flutter 在發(fā)布時(shí)可以通過(guò) AOT 生成高效的 ARM 代碼以保證應(yīng)用性能。而 JavaScript 則不具有這個(gè)能力。
Flutter 旨在提供流暢、高保真的的 UI 體驗(yàn)。為了實(shí)現(xiàn)這一點(diǎn),F(xiàn)lutter 中需要能夠在每個(gè)動(dòng)畫(huà)幀中運(yùn)行大量的代碼。這意味著需要一種既能提供高性能的語(yǔ)言,而不會(huì)出現(xiàn)會(huì)丟幀的周期性暫停,而 Dart 支持 AOT,在這一點(diǎn)上可以做的比 JavaScript 更好。
Flutter 框架使用函數(shù)式流,這使得它在很大程度上依賴(lài)于底層的內(nèi)存分配器。因此,擁有一個(gè)能夠有效地處理瑣碎任務(wù)的內(nèi)存分配器將顯得十分重要,在缺乏此功能的語(yǔ)言中,F(xiàn)lutter 將無(wú)法有效地工作。當(dāng)然 Chrome V8 的 JavaScript 引擎在內(nèi)存分配上也已經(jīng)做的很好,事實(shí)上 Dart 開(kāi)發(fā)團(tuán)隊(duì)的很多成員都是來(lái)自Chrome 團(tuán)隊(duì)的,所以在內(nèi)存分配上 Dart 并不能作為超越 JavaScript 的優(yōu)勢(shì),而對(duì)于 Flutter 來(lái)說(shuō),它需要這樣的特性,而 Dart 也正好滿足而已。
由于 Dart 是類(lèi)型安全的語(yǔ)言,支持靜態(tài)類(lèi)型檢測(cè),所以可以在編譯前發(fā)現(xiàn)一些類(lèi)型的錯(cuò)誤,并排除潛在問(wèn)題,這一點(diǎn)對(duì)于前端開(kāi)發(fā)者來(lái)說(shuō)可能會(huì)更具有吸引力。與之不同的,JavaScript 是一個(gè)弱類(lèi)型語(yǔ)言,也因此前端社區(qū)出現(xiàn)了很多給 JavaScript 代碼添加靜態(tài)類(lèi)型檢測(cè)的擴(kuò)展語(yǔ)言和工具,如:微軟的 TypeScript 以及 Facebook 的 Flow。相比之下,Dart 本身就支持靜態(tài)類(lèi)型,這是它的一個(gè)重要優(yōu)勢(shì)。
看似不起眼,實(shí)則舉足輕重。由于有 Dart 團(tuán)隊(duì)的積極投入,F(xiàn)lutter 團(tuán)隊(duì)可以獲得更多、更方便的支持,正如 Flutter 官網(wǎng)所述“我們正與 Dart 社區(qū)進(jìn)行密切合作,以改進(jìn) Dart 在 Flutter 中的使用。例如,當(dāng)我們最初采用 Dart 時(shí),該語(yǔ)言并沒(méi)有提供生成原生二進(jìn)制文件的工具鏈(這對(duì)于實(shí)現(xiàn)可預(yù)測(cè)的高性能具有很大的幫助),但是現(xiàn)在它實(shí)現(xiàn)了,因?yàn)?Dart 團(tuán)隊(duì)專(zhuān)門(mén)為 Flutter 構(gòu)建了它。同樣,Dart VM 之前已經(jīng)針對(duì)吞吐量進(jìn)行了優(yōu)化,但團(tuán)隊(duì)現(xiàn)在正在優(yōu)化 VM 的延遲時(shí)間,這對(duì)于 Flutter 的工作負(fù)載更為重要?!?/p>
本節(jié)主要介紹了一下 Flutter 的特點(diǎn),如果你感到有些點(diǎn)還不是很好理解,不用著急,隨著日后對(duì) Flutter 細(xì)節(jié)的了解,再回過(guò)頭來(lái)看,相信你會(huì)有更深的體會(huì)。
本節(jié)我們先對(duì) Flutter 的框架做一個(gè)整體介紹,旨在讓讀者心中有一個(gè)整體的印象,這對(duì)初學(xué)者來(lái)說(shuō)非常重要。如果一下子便深入到 Flutter 中,就會(huì)像是一個(gè)在沙漠中沒(méi)有地圖的人,即使可以找到一個(gè)綠洲,但是他也不會(huì)知道下一個(gè)綠洲在哪。因此,無(wú)論學(xué)什么技術(shù),都要先有一張清晰的“地圖”,而我們的學(xué)習(xí)過(guò)程就是“按圖索驥”,這樣我們才不會(huì)陷于細(xì)節(jié)而“目無(wú)全?!?。言歸正傳,我們看一下 Flutter 官方提供的 Flutter 框架圖,如圖 1-1 所示:
這是一個(gè)純 Dart 實(shí)現(xiàn)的 SDK,它實(shí)現(xiàn)了一套基礎(chǔ)庫(kù),自底向上,我們來(lái)簡(jiǎn)單介紹一下:
dart:ui
包,它是 Flutter 引擎暴露的底層UI庫(kù),提供動(dòng)畫(huà)、手勢(shì)及繪制能力。dart:ui
)。
這是一個(gè)純 C++ 實(shí)現(xiàn)的 SDK,其中包括了 Skia 引擎、Dart 運(yùn)行時(shí)、文字排版引擎等。在代碼調(diào)用 dart:ui
庫(kù)時(shí),調(diào)用最終會(huì)走到 Engine 層,然后實(shí)現(xiàn)真正的繪制邏輯。
Flutter 框架本身有著良好的分層設(shè)計(jì),本節(jié)旨在讓讀者對(duì)Flutter整體框架有個(gè)大概的印象,相信到現(xiàn)在為止,讀者已經(jīng)對(duì) Flutter 有一個(gè)初始印象,在我們正式動(dòng)手之前,我們還需要了解一下 Flutter 的開(kāi)發(fā)語(yǔ)言 Dart。
本節(jié)給大家一些學(xué)習(xí)建議,分享一下筆者在學(xué)習(xí) Flutter 中的一些心得,希望可以幫助你提高學(xué)習(xí)效率,避免不必要的坑。
有了資料和社區(qū)后,對(duì)于我們學(xué)習(xí)者自身來(lái)說(shuō),最重要的還是要多動(dòng)手、多實(shí)踐,在本書(shū)后面的章節(jié)中,希望讀者能夠親自動(dòng)手寫(xiě)一下示例。準(zhǔn)備好了嗎,下一章中,我們將正式進(jìn)入 Flutter 的世界!
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: