Flutter是谷歌的移動端UI開源框架,2018年2月27日, Google發佈了Flutter的第一個Beta版本。它是Google使用Dart語言開發的移動應用開發框架,使用Dart代碼構建高性能、高保真的iOS和Android應用程序。Flutter的工具和庫能夠幫助開發者輕鬆地將本身的想法帶到 iOS 和Android 設備上。若是沒有任何移動開發經驗,用Flutter來構建漂亮的移動應用是不錯的選擇。前端
現有的移動平臺:node
蘋果的iOS SDKs發佈於2008年,谷歌的Android軟件開發工具包發佈於2009年,這兩種sdk包是基於不一樣的編程語言的,分別是Objective-C和Java, 以下是大概的結構圖:android
因此帶來的問題是大多數APP要針對不一樣系統提供不一樣版本的應用,由於系統提供的組件和語言不同。隨之而來的問題是如何只開發一套代碼,兩端均可以運行,也就有了以下的三代跨端平臺的出現。ios
這是第一個跨平臺的框架,基於JavaScript 和 WebView 例如 Cordova、PhoneGap、APPCan、Ionic等,應用程序能夠編寫成Html,並最終在移動平臺的Webview中顯示,並經過JavaScript interface和原生交互。git
缺點:github
原生體驗的第二代跨平臺框架,如ReactNative/Weex,生成虛擬DOM,並進一步對應生成原生的組件,讓頁面由原生組件組成,來到達原生的體驗。JS代碼和原生代碼自己都是很快的,瓶頸常常發生在當咱們視圖從一邊轉向另外一邊時,因此構建高質量的應用程序時,咱們必須將使用橋接的次數控制到最小。算法
缺點:編程
第三代跨平臺框架,Flutter也提供響應式的視圖,Flutter採用不一樣的方法避免由JavaScript橋接器引發的性能問題,即用名爲Dart的程序語言來編譯,Dart是用預編譯的方式編譯多個平臺的原生代碼,這容許Flutter直接與平臺通訊,同時使用Skia圖形引擎來完成圖形、文本、圖像、動畫等繪製,擁有本身獨立的一套圖形系統,再也不依賴於原生。緩存
缺點:性能優化
這種分層設計的目的是幫助開發者寫更少的代碼來實現功能。例如,Material層經過組合Widget層的控件來構建,而Widget層自己則依賴Rendering層來構建。上述分層爲咱們開發App提供了不少選擇,首先可使用Flutter提供的現有Widget來組合,或者建立自定義的Widget。
開發者經過實現一個build函數來定義一個Widget,這個build函數會返回一個Widget樹,這棵Widget樹更具體地描述了UI中的Widget層次。例如,一個ToolBar Widget的build函數可能會返回一個水平佈局、一些文本和不一樣的按鈕,框架會遞歸地調用每一個Widget的build函數,直到全部的Widget都遍歷完成,而後將這些Widget組合成一顆Widget樹。
若是Widget的特性基於用戶交互或其餘因素進行改變,則這個Widget是有狀態的,Flutter提供兩種類型的widget, StatelessWidget/StatefulWidget,前者爲狀態不可變,後者能夠經過setState()改變state來改變動新UI,開發者能夠根據本身的實際狀況使用 StatefulWidget:
StatelessWidget:
在Android系統中,咱們一般是使用xml來進行UI佈局,同時能夠經過addChild和removeChild添加或者移除視圖。 可是在Flutter中,Widget 是不可變的,能夠傳入一個函數,該函數返回一個子Widget 給父 Widget。並在該函數中經過一個 bool 值來控制子 Widget 的建立。
Flutter中有兩種方式來處理touch:
在 Android 中咱們能用View.animate()來啓動一個動畫,在Flutter中咱們是把Widget包在Animation中。在 Flutter中,有AnimationController 和Interpolator來控制動畫的啓動。
在 Android 中 咱們能使用Canvas來畫或者定製一些UI。在 Flutter中,有CustomPaint 和 CustomPainter來提供一些算法完成繪畫功能。
在 Android 中 咱們經過繼承實現View/ViewGroup等組件來完成一些自定義的組件,在 Flutter中,不提供繼承這種方式,而是經過一些小的組件組合。
在 Android 中 咱們經過Intents的方式來啓動頁面或者service,在 Flutter中沒有Intent, 咱們就須要route 和 Navigator來管理頁面了,Route能夠看成一個page或者activity,Navigator 是一個widget用來管理routes的,能push或者pop頁面。
在android中,頁面的生命週期都在activity和fragment中控制,可是Flutter只有一個FlutterView, 咱們須要hook WidgetsBinding 的observer並監聽didChangeAppLifecycleState的event消息。
Flutter 頁面切換是經過Router和Navigator完成的,一樣能夠經過result back的方式獲取你push的router返回的數據。
Flutter 是支持原生頁面和Flutter頁面混合開發的,可是不支持原生組件在Flutter中使用,原生端有methodchannel 來支持Flutter對原生的一些API調用。
在Andorid中,咱們有不少相似Okhttp之類的網絡使用,很是方便,在Flutter中,咱們使用http package來簡單的完成一個網絡請求調用。
Flutter 內置有不少 Material Design 和 Cupertino(iOS 風格)的部件、豐富的手勢 API、天然平滑的滑動動畫
從Android端頁面層次來看,主頁面MainActivity是繼承了FlutterActivity,經過FlutterActivityDelegate控制一些初始化,包括FlutterView,而整個Flutter展現的頁面是繪製在FlutterView中的。
Flutter跨平臺的基礎就是UI跨平臺,UI繪製不依賴系統組件, FlutterView將Dart編寫的界面封裝成android平臺可使用的組件,這個組件完成了android應用界面的全部繪製工做,ios也有相同的一套機制,從而實現了不一樣平臺共用一套繪製界面的代碼。
FlutterView繼承了SurfaceView,從API中能夠看出SurfaceView屬於View的子類,提供雙緩存功能,它是專門爲製做遊戲而產生的,功能很是強大,最重要的是它支持OpenGL ES庫,2D和3D的效果都,既然Flutter界面是直接繼承於SurfaceView的,它的繪製過程就再也不依賴於系統平臺,解耦了系統控件的調用。
採用MethodChanel實現7個消息模塊管理:多語言、路由導航、按鍵消息、生命週期、系統信息、用戶設置和平臺插件,這幾乎涵蓋了不一樣平臺全部差別化最大的功能,並且很是依賴原生系統。
MethodChanel:
下面咱們以keyevent爲例子簡單說明事件傳遞機制:
FlutterView類有兩個處理按鍵事件的接口,一個是onKeyUp(),一個是onKeyDown(),分別對應按鍵鬆開和按下事件,兩個方法流程同樣,Flutter再將平臺的按鍵事件以消息方式攔截,具體步流程建議參考源碼:
能夠看到Flutter架構裏面只有一個FlutterView用來呈現全部的widget的佈局的,因此整個渲染過程是獨立於原生UI,而ReactNative和原生是比較相似的,會將js中的UI組件一一對應到原生組件。
Flutter UI層次:
ReactNative UI層次:
咱們作了一個簡單demo,測試滑動一個有100條數據的list,內存上Flutter和原生相差不大,比較穩定,ReactNative內存波動比較大。CPU方面Flutter比較原生高了接近兩倍,相比ReactNative也明顯要高。GPU方面Flutter除了初始化時GPU比較高,應該是初始化FlutterView,後面的拖動過程當中看不到GPU的渲染,緣由應該是獨立的渲染體系,android studio 提取不出來。因此總體而言原生的性能是最佳的。
Flutter性能:
ReactNative性能:
原生性能:
Flutter debug包下,lib庫包含86_64/x86/armeabi-v7a,接近50M,考慮如今的手機支持X86比較少,在release包中只包含了armeabi-v7a,lib庫大小壓縮到了3.3M,整個APK壓縮後將在7.5M左右,其餘資源大部分是Flutter的代碼,主要集中在assets下,並且有優化空間。 相比較於ReactNative,自己的SDK庫在3.5M左右,簡單的頁面對應的JS包大小在300K左右,佔用空間能減小很多,可是Flutter是本身實現的一套engine,徹底獨立於系統平臺,佔用比較大,其實也能理解。
Flutter apk結構:
ReactNative apk結構:
原生結構:
ReactNative是基於前端思想開發的框架,對於原生複雜的ListView/Gridview等容器,沒有辦法直接實現,並且還有些複雜的UI依賴於View的嵌套疊加,在這種設計,相比較原生的設計,就會多出不少的View,相比native 實現來講會多不少view對象,形成了性能下降。也就是說複雜UI需求下,RN對UI的表達效率遠低於native,形成性能低下。Flutter是基於Skia本身實現的UI組件庫,因此在佈局和動畫層次上有跟多的靈活性和性能優化空間,能夠作到最優化。
開發語言上, js或dart都是一種聲明式的寫法,但js須要解釋,dart是直接語言層面支持了node tree的書寫,且對象建立成本低,可直接編譯成native代碼(AOT),VM效率更高,因此運行上dart效率高不少, 並且Dart 是一種同時支持 JIT/AOT 編譯的語言,JIT 開發模式時能快速編譯生效,是Hot Reload體驗的關鍵。
Flutter所提供的全部的widget/動畫還有事件機制都是基於skia來實現的,與平臺無關,因此有很高的跨平臺的兼容性。可是獨立的UI系統致使了,不少Android/iOS對應的工具沒法使用。
ReactNative全部的組件都是依賴於原生的,而Android/iOS自己的組件和實現就不同,致使了不少兼容性問題,不一樣平臺要作適配和橋接,致使了不少的功能成本/開發成本和性能犧牲,好比動畫/手勢/數據容器等等。
Flutter 提供的widget都是基於skia來實現和精心定製的,與具體平臺沒關,因此能保持很高的跨平臺的兼容性,對將來平臺的適應性上Flutter從更基礎的層去抹平平臺差別,Flutter站在了更寬廣、更可控的一個基礎平臺上去演變和發展。ReactNative永遠須要follow native開發的這套約束,橋接和抹平差別乃至應用層去適配的成本、面對具體場景去優化性能所須要的成本都是居高不下的。
Flutter引擎+Dart語言將頗有可能成爲Google Fuchsia系統主要的UI開發框架, 這將會將其跨平臺的特性發揮的淋漓盡致。
總之從Flutter的設計理念來看,總體架構都是具備革命性的,相比於其餘跨平臺實現了真正意義的跨平臺,各平臺體驗一致,並且讓用戶體驗達到了最優,各類UI庫和組件也在不斷的增長,各類生態系統和社區在不斷的完善,對於之後新的操做系統適配性會更強,如Fuchsia系統,很是值得你們瞭解和學習,相信不久的未來,會慢慢成熟起來,成爲主流開發語言。
ARES團隊也在持續保持更新,將來會和JDReact引擎一塊兒成爲京東多端融合平臺的雙引擎。