Flutter實(shí)戰(zhàn) 初識(shí)Flutter

2021-03-06 14:29 更新

1.2.1 Flutter簡(jiǎn)介

FlutterGoogle 推出并開(kāi)源的移動(dòng)應(yīng)用開(kāi)發(fā)框架,主打跨平臺(tái)、高保真、高性能。開(kāi)發(fā)者可以通過(guò) Dart 語(yǔ)言開(kāi)發(fā) App,一套代碼同時(shí)運(yùn)行在 iOSAndroid 平臺(tái)。 Flutter 提供了豐富的組件、接口,開(kāi)發(fā)者可以很快地為 Flutter 添加 native 擴(kuò)展。同時(shí) Flutter還使用 Native 引擎渲染視圖,這無(wú)疑能為用戶提供良好的體驗(yàn)。

#跨平臺(tái)自繪引擎

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)。

#采用Dart語(yǔ)言開(kāi)發(fā)

這是一個(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ì)比):

  1. 開(kāi)發(fā)效率高

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è)能力。

  1. 高性能

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 更好。

  1. 快速內(nèi)存分配

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 也正好滿足而已。

  1. 類(lèi)型安全

由于 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ì)。

  1. Dart團(tuán)隊(duì)就在你身邊

看似不起眼,實(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é)

本節(jié)主要介紹了一下 Flutter 的特點(diǎn),如果你感到有些點(diǎn)還不是很好理解,不用著急,隨著日后對(duì) Flutter 細(xì)節(jié)的了解,再回過(guò)頭來(lái)看,相信你會(huì)有更深的體會(huì)。

#1.2.2 Flutter框架結(jié)構(gòu)

本節(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 所示:

圖1-1

#Flutter Framework

這是一個(gè)純 Dart 實(shí)現(xiàn)的 SDK,它實(shí)現(xiàn)了一套基礎(chǔ)庫(kù),自底向上,我們來(lái)簡(jiǎn)單介紹一下:

  • 底下兩層(Foundation和Animation、Painting、Gestures)在 Google 的一些視頻中被合并為一個(gè) dart UI 層,對(duì)應(yīng)的是 Flutter 中的dart:ui包,它是 Flutter 引擎暴露的底層UI庫(kù),提供動(dòng)畫(huà)、手勢(shì)及繪制能力。
  • Rendering 層,這一層是一個(gè)抽象的布局層,它依賴(lài)于 dart UI 層,Rendering 層會(huì)構(gòu)建一個(gè) UI 樹(shù),當(dāng) UI 樹(shù)有變化時(shí),會(huì)計(jì)算出有變化的部分,然后更新 UI 樹(shù),最終將 UI 樹(shù)繪制到屏幕上,這個(gè)過(guò)程類(lèi)似于 React 中的虛擬 DOM。Rendering 層可以說(shuō)是 Flutter UI 框架最核心的部分,它除了確定每個(gè) UI 元素的位置、大小之外還要進(jìn)行坐標(biāo)變換、繪制(調(diào)用底層 dart:ui)。
  • Widgets 層是 Flutter 提供的的一套基礎(chǔ)組件庫(kù),在基礎(chǔ)組件庫(kù)之上,F(xiàn)lutter 還提供了 Material 和 Cupertino 兩種視覺(jué)風(fēng)格的組件庫(kù)。而我們 Flutter 開(kāi)發(fā)的大多數(shù)場(chǎng)景,只是和這兩層打交道。

#Flutter Engine

這是一個(gè)純 C++ 實(shí)現(xiàn)的 SDK,其中包括了 Skia 引擎、Dart 運(yùn)行時(shí)、文字排版引擎等。在代碼調(diào)用 dart:ui庫(kù)時(shí),調(diào)用最終會(huì)走到 Engine 層,然后實(shí)現(xiàn)真正的繪制邏輯。

#總結(jié)

Flutter 框架本身有著良好的分層設(shè)計(jì),本節(jié)旨在讓讀者對(duì)Flutter整體框架有個(gè)大概的印象,相信到現(xiàn)在為止,讀者已經(jīng)對(duì) Flutter 有一個(gè)初始印象,在我們正式動(dòng)手之前,我們還需要了解一下 Flutter 的開(kāi)發(fā)語(yǔ)言 Dart。

#1.2.3 如何學(xué)習(xí)Flutter

本節(jié)給大家一些學(xué)習(xí)建議,分享一下筆者在學(xué)習(xí) Flutter 中的一些心得,希望可以幫助你提高學(xué)習(xí)效率,避免不必要的坑。

#資源

  • 官網(wǎng):閱讀 Flutter 官網(wǎng)的資源是快速入門(mén)的最佳方式,同時(shí)官網(wǎng)也是了解最新 Flutter 發(fā)展動(dòng)態(tài)的地方,由于目前 Flutter 仍然處于快速發(fā)展階段,所以建議讀者還是時(shí)不時(shí)的去官網(wǎng)看看有沒(méi)有新的動(dòng)態(tài)。
  • 源碼及注釋:源碼注釋?xiě)?yīng)作為學(xué)習(xí) Flutter 的第一文檔,F(xiàn)lutter SDK 的源碼是開(kāi)源的,并且注釋非常詳細(xì),也有很多示例,實(shí)際上,F(xiàn)lutter 官方的 SDK 文檔就是通過(guò)注釋生成的。源碼結(jié)合注釋可以幫你解決大多數(shù)問(wèn)題。
  • Github:如果遇到的問(wèn)題在 StackOverflow 上也沒(méi)有找到答案,可以去 github flutter 項(xiàng)目下提 issue。
  • Gallery源碼:Gallery 是 Flutter 官方示例 APP,里面有豐富的示例,讀者可以在網(wǎng)上下載安裝。Gallery 的源碼在 Flutter 源碼“examples”目錄下。

#社區(qū)

  • StackOverflow:如果你還沒(méi)聽(tīng)過(guò) StackOverflow,這是目前全球最大的程序員問(wèn)答社區(qū),現(xiàn)在也是活躍度最高的 Flutter 問(wèn)答社區(qū)。StackOverflow 上面除了世界各地的 Flutter 使用者會(huì)在上面交流之外,F(xiàn)lutter 開(kāi)發(fā)團(tuán)隊(duì)的成員也經(jīng)常會(huì)在上面回答問(wèn)題。
  • Flutter中文網(wǎng)社區(qū)Flutter 中文網(wǎng)是筆者維護(hù)中文網(wǎng)站,目前也是最大的中文資源社區(qū),上面提供了Flutter 官網(wǎng)的文檔翻譯、開(kāi)源項(xiàng)目、及案例,還有申請(qǐng)加入組織的入口哦。
  • 博客:隨著 Flutter 技術(shù)的推廣,相信很快網(wǎng)上將會(huì)有很多 Flutter 相關(guān)的文章、博客,讀者可以多去瀏覽、閱讀。

#總結(jié)

有了資料和社區(qū)后,對(duì)于我們學(xué)習(xí)者自身來(lái)說(shuō),最重要的還是要多動(dòng)手、多實(shí)踐,在本書(shū)后面的章節(jié)中,希望讀者能夠親自動(dòng)手寫(xiě)一下示例。準(zhǔn)備好了嗎,下一章中,我們將正式進(jìn)入 Flutter 的世界!

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)