Flutter基礎(chǔ)結(jié)構(gòu)
Flutter是谷歌的移動UI框架脐供,用于在創(chuàng)紀錄的時間內(nèi)在iOS和Android上制作高質(zhì)量的本地界面。Flutter與現(xiàn)有代碼一起工作件蚕,被世界各地的開發(fā)人員和組織使用帜消,并且是免費和開源的端姚×镒澹可以看出flutter是移動UI框架讹俊,和系統(tǒng)沒有太大的關(guān)系雏掠。下面我看看flutter的架構(gòu)圖:
從架構(gòu)圖可以看出其就分為兩個部分,F(xiàn)ramework和Engine部分劣像。其中Framework提供了各種基礎(chǔ)的組件庫,Engine部分渲染各種widget摧玫,兩者共同作用耳奕,使得運行性能高效穩(wěn)定。
- Framework部分
這一部分最底層是Foundation诬像,也就是與Engine引擎相關(guān)的一些方法api屋群,上一層就是動畫繪制還有手勢相關(guān),其次才是Rendering相關(guān)坏挠,然后才是我們Flutter重要Widget芍躏,可以看出動畫手勢繪制都會重新出發(fā)render,Widget才會重新繪制降狠。在Widget之上有兩種設計的風格分別是iOS的Cupertino與Android的Material兩種風格的組件庫对竣。 -
Engine部分
底下引擎部分就是Flutter與Cordova、Ionic榜配、AppCan否纬、Dcloud、APICloud蛋褥、React Native這些框架最根本不同的地方临燃,F(xiàn)lutter不是使用標準Web技術(shù),而是借助可移植的圖形加速渲染引擎烙心、高性能的本地ARM代碼膜廊,并以此實現(xiàn)跨設備、跨平臺的高質(zhì)量用戶體驗淫茵。
可以看出Dart維護的UI線程爪瓜,其中我們我們用到的Widget樹在使用GPU線程進行繪制。最后回調(diào)到Skia中后到GPU去工作匙瘪。這種方式其實是和原生是一樣的钥勋,性能是可以與原生App一模一樣的。不僅于此,Google還對這一部分做了優(yōu)化操作掩完,讓其性能超過了原生啥么。可以看看RN的繪制過程:
學過RN的都知道它是用了JSX語法菲驴,那么JSX語法是什么?傳統(tǒng)的Web應用中會有成千上萬數(shù)量個DOM節(jié)點骑冗,所以更新的時候會非成匏玻瑣碎先煎、頻繁,使頁面加載緩慢巧涧,所以現(xiàn)代的Web應用開始使用虛擬DOM技術(shù)來提高頁面更新的速度薯蝎,用一個虛擬DOM,而不是直接調(diào)用類似.getElementById的方法谤绳,只操作JavaScript對象占锯,然后再把更改的部分更新到真實DOM,這樣是相當方便的缩筛。這就是JSX干的事情消略,這個其實也是借鑒了Android與iOS原生的思路,原生只不過不是DOM瞎抛,而是虛擬控件艺演,這樣的設計速度快了很多,也是非常方便桐臊,但是添加了虛擬DOM意味著更多的代碼胎撤,而且在一個DOM節(jié)點相對較少的頁面中用虛擬DOM,實際上有可能會更慢断凶。但是可以利用硬件性能來滿足于解決這個問題哩照。那么Flutter是如何做的?可以看下圖:
在Flutter的響應式框架中懒浮,控件樹中的控件直接通過可移植的圖形加速渲染引擎飘弧、高性能的本地ARM代碼進行繪制,不再需要通過虛擬DOM或虛擬控件砚著、真實DOM或平臺控件這些中間對象來繪制次伶。Flutter響應式框架通過“無中間商賺差價”的方式直接利用硬件的所有性能,所以正如前面所說的稽穆,F(xiàn)lutter應用的性能比原生App更加優(yōu)秀冠王。
Flutter如何構(gòu)建一個APP
通過創(chuàng)建的Flutter項目我們可以知道,整個程序的入口在一個叫main.dart文件中舌镶,這個文件的內(nèi)如下:
void main() => runApp(Widget app);
這個很好理解柱彻,因為整個Flutter都是基于dart語言開發(fā)的,所以程序入口肯定也是在一個main函數(shù)中餐胀,main()函數(shù)中只調(diào)用runApp函數(shù)哟楷,使用runApp函數(shù)可以將給定的根控件填滿整個屏幕。你可能會有疑問否灾,為什么一定要使用runApp函數(shù)卖擅?如果不調(diào)用runApp函數(shù),項目也可以正常執(zhí)行,但是屏幕上什么都不會顯示惩阶。Flutter是Dart語言的移動應用框架挎狸,runApp函數(shù)就是Flutter框架的入口,如果不調(diào)用runApp函數(shù)断楷,那你執(zhí)行的就是一個Dart控制臺應用锨匆。可以看出啟動一個flutter app其實就是創(chuàng)建一個dart的主線程冬筒,具體還得看binding.dart中的runApp函數(shù)這個函數(shù)恐锣,函數(shù)主要就是WidgetsFlutterBinding方法中的attachRootWidget綁定了傳入的根目錄的Widget。到后面一層層的初始化Widget樹账千。