引言
說到Flutter缔俄,絕對繞不開Fuchsia挖炬,這個是谷歌開發(fā)的一款全新的操作系統(tǒng)Fuchsia內(nèi)核是Magenta Kernel,一個基于LittleKernel的項(xiàng)目。該系統(tǒng)與Android相比,無論是存儲器還是內(nèi)存之類的硬件要求都大幅降低项炼,外界推論是一款面向物聯(lián)網(wǎng)的系統(tǒng),具體是做什么的目前不得而知,但這不是我們所講的重點(diǎn)
What Is Flutter?
官方介紹
- 快速開發(fā):Flutter的熱重載可以快速地進(jìn)行測試、構(gòu)建UI、添加功能并更快地修復(fù)錯誤。
- 富有表現(xiàn)力,漂亮的用戶界面:自帶的Material Design和Cupertino(iOS風(fēng)格)widget、豐富的motion API吨述、平滑而自然的滑動效果亿笤。
- 響應(yīng)式框架:使用Flutter的現(xiàn)代燃领、響應(yīng)式框架猛蔽,和一系列基礎(chǔ)widget叮称,輕松構(gòu)建您的用戶界面。
- 訪問本地功能和SDK:Flutter可以復(fù)用現(xiàn)有的Java、Swift或ObjC代碼绍移,訪問iOS和Android上的原生系統(tǒng)功能和系統(tǒng)SDK横媚。
- 統(tǒng)一的應(yīng)用開發(fā)體驗(yàn):Flutter擁有豐富的工具和庫狡忙,可以幫助開發(fā)者輕松地同時在iOS和Android系統(tǒng)中實(shí)現(xiàn)想法和創(chuàng)意。
- 原生性能:Flutter包含了許多核心的widget淑廊,如滾動逗余、導(dǎo)航、圖標(biāo)和字體等季惩,這些都可以在iOS和Android上達(dá)到原生應(yīng)用一樣的性能录粱。
定義
Flutter是Google一個新的用于構(gòu)建跨平臺的手機(jī)App的SDK
跨平臺應(yīng)用的框架腻格,沒有使用WebView或者系統(tǒng)平臺自帶的控件,使用自身的高性能渲染引擎自繪
簡化版的瀏覽器啥繁,最大限度在android和ios上統(tǒng)一UI菜职,包括業(yè)務(wù)邏輯和用戶體驗(yàn)
開發(fā)語言使用dart,結(jié)合C, C++, 和Skia(2D渲染引擎)構(gòu)建
支持hot reload旗闽,包含著完整的控件和工具鏈
一切皆控件酬核,控件是每個Flutter應(yīng)用程序的基本構(gòu)建塊,與分離視圖适室、控制器嫡意、布局和其他屬性的框架不同,F(xiàn)lutter具有一致的統(tǒng)一對象模型:控件捣辆。一個控件可以定義:結(jié)構(gòu)元素(比如按鈕或菜單)蔬螟、風(fēng)格元素(比如字體或顏色方案)、布局的方面(比如填充)、一些業(yè)務(wù)邏輯等
組合大于繼承,控件本身通常由許多小型队塘、單用途的控件組成,結(jié)合起來產(chǎn)生強(qiáng)大的效果菠齿,類的層次結(jié)構(gòu)是扁平的,以最大化可能的組合數(shù)量
強(qiáng)化版的WebView坐昙,框架僅提供一個View層,大部分功能要依賴原生
目前只能夠運(yùn)行大部分Dart代碼(不能引入dart:mirrors或dart:html庫)
核心原則
Flutter 包含了一個函數(shù)響應(yīng)式框架( functional-reactive framework)芋忿、一個 2D 渲染引擎炸客、直接可用的 Widget 庫、和各種開發(fā)工具戈钢。這些組件在一起配合使用痹仙,來幫助你設(shè)計、開發(fā)殉了、測試和調(diào)試 應(yīng)用开仰。這些功能都圍繞幾個核心的原則來實(shí)現(xiàn)的。
Why Flutter薪铜?
高生產(chǎn)率
- 一套代碼可以開發(fā)出 Android 和 iOS 應(yīng)用
- 同樣的功能只需要很少的代碼众弓,如果你只開發(fā)一個平臺的應(yīng)用,使用 時髦的隔箍、更具有表達(dá)性的開發(fā)語言谓娃,也可以讓你用更少的代碼來實(shí)現(xiàn)同樣的功能。
- 開發(fā)原型和迭代更加方便
- 在 應(yīng)用運(yùn)行的時候就可以修改代碼并重新加載修改后的功能
- 直接修改崩潰的 bug蜒滩,然后繼續(xù)從崩潰的地方執(zhí)行調(diào)試
創(chuàng)建優(yōu)雅的滨达、可定制的用戶界面
- Flutter 內(nèi)置了對紙墨設(shè)計(Material Design)的支持奶稠,提供了豐富的 UI 控件庫可以用來創(chuàng)建紙墨設(shè)計風(fēng)格的 UI
- 提供了可定制的 UI 框架,不再受制于手機(jī)平臺控件的支持
Flutter SDK體積為什么非常大捡遍?
- Flutter應(yīng)用的體積由兩部分組成:應(yīng)用代碼和 SDK代碼锌订。應(yīng)用代碼是 Dart編譯后的代碼,如果做成可動態(tài)下發(fā)画株,那么這部分可以不計辆飘。 SDK代碼比較大就有點(diǎn)無奈了,SDK的組成部分有 Dart VM污秆,Dart標(biāo)準(zhǔn)庫劈猪,libwebp、libpng良拼、libboringssl等第三方庫战得,libskia,Dart UI庫庸推,然后再加上 icu_data常侦,可能在單 arch下(iOS),SDK體積達(dá)到 40+MB贬媒。其中僅僅 Dart VM(不包含標(biāo)準(zhǔn)庫)就達(dá)到了 7MB聋亡。 Flutter SDK是 dynamic framework,如此大的二進(jìn)制體積可能會造成動態(tài)鏈接耗時長际乘。而如果靜態(tài)鏈接坡倔,可能原來比較大的 App很有可能造成 TEXT段超標(biāo)。
How Flutter?
運(yùn)行機(jī)制
Flutter 應(yīng)用運(yùn)行在一個用 C++ 寫的引擎中脖含,F(xiàn)lutter 應(yīng)用可以看做是一個游戲 App罪塔,代碼都是在引擎中運(yùn)行。
Android
引擎的C或C++代碼是由Android NDK編譯的养葵,而框架的主要代碼和應(yīng)用的代碼由Dart compiler編譯成native code執(zhí)行的征堪。
對于Android應(yīng)用來說,F(xiàn)lutter框架在引擎中實(shí)現(xiàn)了一個繼承于SurfaceView的 FlutterView关拒。用戶所看到的UI都是在這個SurfaceView中顯示佃蚜。如果要和原生平臺功能交互,則可以在Activity中使用FlutterView着绊,并通過Flutter提供的消息API和原生平臺收發(fā)消息谐算。
ios
- 引擎的C或C++代碼是由LLVM編譯的,而所有Dart的代碼會被AOT編譯成native code畔柔,整個APP運(yùn)行時使用的是機(jī)器指令(并不是攔截器)氯夷。
系統(tǒng)架構(gòu)
Flutter Framework: 這是一個純 Dart實(shí)現(xiàn)的 SDK,類似于 React在 JavaScript中的作用靶擦。它實(shí)現(xiàn)了一套基礎(chǔ)庫腮考, 用于處理動畫雇毫、繪圖和手勢。并且基于繪圖封裝了一套 UI組件庫踩蔚,然后根據(jù) Material 和Cupertino兩種視覺風(fēng)格區(qū)分開來棚放。這個純 Dart實(shí)現(xiàn)的 SDK被封裝為了一個叫作 dart:ui的 Dart庫。我們在使用 Flutter寫 App的時候馅闽,直接導(dǎo)入這個庫即可使用組件等功能飘蚯。
-
Flutter Engine: 這是一個純 C++實(shí)現(xiàn)的 SDK,其中囊括了 Skia引擎福也、Dart運(yùn)行時局骤、文字排版引擎等。不過說白了暴凑,它就是 Dart的一個運(yùn)行時峦甩,它可以以 JIT、JIT Snapshot 或者 AOT的模式運(yùn)行 Dart代碼现喳。在代碼調(diào)用 dart:ui庫時凯傲,提供 dart:ui庫中 Native Binding 實(shí)現(xiàn)。 不過別忘了嗦篱,這個運(yùn)行時還控制著 VSync信號的傳遞冰单、GPU數(shù)據(jù)的填充等,并且還負(fù)責(zé)把客戶端的事件傳遞到運(yùn)行時中的代碼灸促。
-
整個 Flutter Engine可以粗略地劃分為三個部分:Dart UI诫欠、Runtime、Shell
繪制流程
入口
- 界面的布局和繪制在每一幀都在發(fā)生著浴栽,甚至界面沒有變化呕诉,它也會存在;可以想象每一幀里面吃度,引擎都像流水線的一樣重復(fù)著幾個過程:build(構(gòu)建控件樹),layout(布局), paint(繪制)和 composite(合成)贴硫,周而復(fù)始椿每。驅(qū)動整個流水線的入口是WidgetBinding.drawFrame方法。
void drawFrame() {
...
try {
if (renderViewElement != null)
buildOwner.buildScope(renderViewElement);
super.drawFrame();
buildOwner.finalizeTree();
} finally {
...
}
...
}
布局約束
- 根據(jù)parent給予的約束條件來計算size英遭,而設(shè)置size只能在performResize或者performLayout中進(jìn)行间护,如果設(shè)置sizedByParent為true,則只能在performResize中進(jìn)行挖诸,否則就只能在performLayout中與child的布局同時進(jìn)行汁尺。