移動互聯網發展十餘年,伴隨着 Android、iOS 等智能手機的不斷普及,移動端已逐步取代 PC 端,成爲兵家必爭之地。正所謂「得移動端者得天下」,移動端已成爲互聯網領域最大的流量分發入口,一大批互聯網公司正是在這大趨勢下崛起。前端
伴隨着移動互聯網的高速發展,公司間競爭愈來愈激烈,如何將好想法快速落地、快速試錯,成爲備受關注的問題。提高研發效率、縮短研發週期,保障產品快速試錯並能快速迭代新功能,讓新產品新功能以最快的速度同時抵達 Android、iOS 等多端用戶。java
衆所周知,Android 應用採用 Java 或 Kotlin 編寫,iOS 應用採用 Objective-C 或 Swift 編寫,Web 端採用 HTML /CSS/JavaScript 編寫。當須要開發支持多端的應用,每一端都須要獨立研發、測試,一直到上線,以及後續的維護工做,工做量成倍增漲,勢必延長研發週期。web
爲了解決多端獨立開發的問題,跨平臺技術便應運而生,各大互聯網公司爲此都投入大量人力,因而出現了各類跨平臺技術框架,面對移動領域的跨平臺技術方案的層出不窮,又該如何作技術選型呢?算法
做爲移動端的跨端技術方案,所關注無外乎如下這4個方面:研發效率、動態性、多端一致性、性能體驗。shell
對研發效率和體驗的不斷追逐,移動端的跨平臺技術方框架層出不窮,然則天下武功衆多,萬變不離其宗,從其核心本質來劃分,可大體分爲如下三大類:編程
跨平臺技術,一直以來是每個有追求的開發者所追逐的夢想,同時也是守舊者的噩夢,跨平臺的多端一體化方案勢必顛覆現有的原生各端獨立開發模式,接下來列舉衆多的跨平臺技術中最爲關鍵的幾個技術方案的演進階段。小程序
從上圖能夠看出,技術演進過程大體分如下三個階段: 第一階段,採用WebView技術繪製界面的Hybrid混合開發技術,經過JS Bridge 將系統部分能力暴露給 JS 調用,其缺點是性能較差,功能受限,擴展性差,不適合交互複雜的場景,好比Cordova。 第二階段,針對WebView界面性能等問題,因而繪製交還原生渲染,僅僅經過JS調用原生控件,相比WebView技術性能體驗更好,這是目前絕大部分跨平臺框架的設計思路,好比React Native、Weex。另外,最近小程序也比較火,第一和第二階段的融合,依然採用WebView做爲渲染容器,經過限制Web技術棧的子集,規範化組件使用,並逐步引入原生控件表明WebView渲染,以提高性能。 第三階段,雖然經過橋接技術使用原生控件解決了功能受限問題,提高性能體驗,但相比原生體驗差距仍是比較大,以及處理平臺差別性很是耗費人力。因而Flutter提出自帶渲染引擎的解決方案,儘量減小不一樣平臺間的差別性, 同時媲美原生的高性能體驗,所以業界對 Flutter有着極高的關注度。markdown
面對現有的如此多跨平臺方案,爲什麼當下最火的跨平臺技術是Flutter,有哪些優點呢?架構
RN、Weex均使用JavaScript做爲編程語言,JavaScript做爲前端開發語言,在跨平臺開發中可謂大放異彩,利用web技術不只能開發出網站,也能夠開發手機端web應用和移動端應用程序,似有一統三界(Android、iOS、Web)的趨勢,這就是你們常說的「大前端」時代。這些技術方案流暢度不太好,平臺一致性較差,至今還沒能大面積取代原生開發。併發
Flutter是以Dart語言編寫,開發體驗更接近客戶端,從你們使用反饋來看也是如此,Flutter開發環境這一套的流程對於前端開發來講並不太友好。Flutter的定位一樣是多端一體化,可是以客戶端爲首,先磨平Android和iOS雙端開發體驗,再逐步向Web端滲透,從Flutter規劃的Roadmap也能看出,Flutter for web目前仍處於預覽版,Flutter客戶端方向都已經如火如荼上線了很多應用。
在此以前,你們常說「大前端」,對於Flutter技術,在筆者看來稱之爲「大移動端」更貼切,Flutter的UI框架優先支持客戶端(Android/iOS)應用的同時,而後再適配Web端。移動互聯網時代,很多公司都制定「移動優先」的戰略,甚至只開發移動端,沒有Web端。移動互聯網的時代造就「大移動端」,Flutter做爲一款能作到媲美原生的高性能跨平臺技術方案,或許一統天下。
在跨平臺技術領域,只要挑戰在,技術就不會停滯,伴隨着技術不斷演進與革新,終將走向美好。
Flutter是完全的跨平臺方案,既沒有采用webView,也沒有采用JS橋接原生控件,而是自行實現一套UI框架,在引擎底層經過Skia渲染到屏幕。對於UI以外所須要使用的移動設備自身提供的服務,好比相機、定位、屏幕觸摸等,則採用Platform Channels跟原生系統通訊的方式來實現。
對於Flutter優點,回到前面講到移動端技術選型的4要素,研發效率、動態性、多端一致性、性能體驗,分別對應下面這一組詞語。
圖解:
固然,不得不說目前的Flutter確實不夠盡善盡美,會存在一些不夠盡善盡美之處,好比生態不夠健全,包體積問題,但其該方案的上限比較高,想象空間比較大,相信更多開發者參與進來,通過更多打磨,將來會作得更好。
2017年5月Google I/O大會正式對外公佈Flutter,到2018年12月發佈Flutter1.0,引起全球大量的開發者和企業開始研究Flutter。StackOverflow 2019年的全球開發者文件調查中,Flutter被評選爲最受開發者歡迎的框架之一,超過了TensorFlow和Node.js。
到目前,全球愈來愈多的公司已經在你們耳熟能詳的知名APP中使用Flutter技術並落地,尤爲國內知名互聯網公司對Flutter投入度很大,社區也是很是活躍。
目前Flutter主要在移動端Android/iOS雙端跨端,Flutter 的願景是成爲一個多端運行的 UI 框架,可以支持不只僅是移動端,還包括Web、桌面、甚至嵌入式設備。在2019 Google I/O 開發者大會上推出的使用 Flutter 開發 Web 應用的框架,同年9月發佈Flutter 1.9,並將Flutter web合入Flutter主倉庫。
從架構圖看,Flutter採用同一個Dart Framework層來統一Flutter C++引擎和Web引擎,最終能夠運行在Android,iOS,Browser上,從Flutter引擎代碼不難看出Flutter也是支持Fuchsia操做系統。
Fuchsia是Google內部正在開發的一款新的操做系統,採用Flutter做爲系統默認的UI框架,也就是說Flutter自然支持Fuchsia,這無疑讓Flutter在衆多的跨平臺方案更有優點。
從Fuchsia技術架構來看,內核層zircon的基礎LK是專爲嵌入式應用中小型系統設計的內核,代碼簡潔,適合嵌入式設備和高性能設備,好比IOT、移動可穿戴設備等,目前這些領域尚未標準化級別的壟斷者。以及在框架層中有着語音交互、雲端以及智能化等模塊,由此筆者揣測將來Fuchsia率先應用在音控等智能嵌入式設備。
目前你們廣泛比較看好的將來兩個技術就是5G和IoT時代。對於5G的需求,很大程度上是由於移動互聯網發展到「IoT時代」的階段。這個發展階段,全球上網設備的數量可能會達到500億個。隨着5G+IOT時代的到來,如今你們比較關注的Flutter包大小也一樣再也不是一個問題,或許Flutter技術的生命期比客戶端更長,或許Fuchsia正在馳騁IOT疆場,你所掌握的Flutter技術棧能夠無縫遷移,一次彎道超車的機會。
到此,介紹完跨平臺技術演進以及Flutter的優點。看到這,相信你可能對Flutter技術有必定興趣,爲了能讓你們快速瞭解Flutter內部原理而不枯燥,Gityuan經過一系列圖來幫你們從總體架構來快速理解Flutter。
先來看看Flutter總體的技術架構,分爲四層,從上之下依次是Dart APP,Dart Framework, C++ Engine,Platform。
Flutter架構最核心的即是Framework(框架)和Engine(引擎):
看完Flutter內部架構,或許你好奇,Flutter不用Android/iOS的本地語言技術開發,Dart編寫完的代碼如何讓不一樣系統能夠識別,最終編譯後獲得的產物是什麼呢?
Flutter產物分爲Dart業務代碼和Engine代碼各自生成的產物,圖中的Dart Code包含開發者編寫的業務代碼,Engine Code是引擎代碼,若是並無定製化引擎,則無需從新編譯引擎代碼。
一份Dart代碼,可編譯生成雙端產物,實現跨平臺的能力。通過編譯工具處理後可生成雙端產物,圖中即是release模式的編譯產物,Android產物是由vm、isolate各自的指令段和數據段以及flutter.jar組成的app.apk,iOS產物是由App.framework和Flutter.framework組成的Runner.app。
這個過程涉及frontend_server、gen_snapshot、xcrun、ninja編譯工具。frontend_server前端編譯器會進行詞法分析、語法分析以及相關全局轉換等工做,將dart代碼轉換爲AST(抽象語法樹),並生成app.dill格式的dart kernel。gen_snapshot通過CHA、內聯等一系列執行流的優化,根據中間代碼生成優化後的FlowGraph對象,再轉換爲具體相應系統架構(arm/arm64等)的二進制指令。
既然瞭解了Flutter的編譯產物,那你或許又好奇,Flutter這臺引擎如何發動的,怎麼跟Native銜接呢?
這裏以Android爲例,熟悉Android的開發者,應該都瞭解APP啓動過程,會執行Application和Activity的onCreate()方法,FlutterApplication和FlutterActivity的onCreate()方法正是鏈接Native和Flutter的樞紐。
Flutter引擎啓動中會建立有4個TaskRunner以及建立虛擬機,分別來看看它們的工做原理。
Flutter引擎啓動過程,會建立UI/GPU/IO這3個線程,會爲這些線程依次建立MessageLoop對象,啓動後處於epoll_wait等待狀態。對於Flutter的消息機制跟Android原生的消息機制有不少類似之處,都有消息(或者任務)、消息隊列(或任務隊列)以及Looper;有一點不一樣的是Android有一個Handler類,用於發送消息以及執行回調方法,相對應Flutter中有着相近功能的即是TaskRunner。
上圖是從源碼中提煉而來的任務處理流程,比官方流程圖更容易理解一些複雜流程的時序問題,後續會專門講解箇中起因。Flutter的任務隊列處理機制跟Android的消息隊列處理相通,只不過Flutter分爲Task和MicroTask兩種類型,引擎和Dart虛擬機的事件以及Future都屬於Task,Dart層執行scheduleMicrotask()所產生的屬於Microtask。
每次Flutter引擎在消費任務時調用FlushTasks()方法,遍歷整個延遲任務隊列delayed_tasks_,將已到期的任務加入task隊列,而後開始處理任務。
可簡單理解爲先處理完全部的Microtask,而後再處理Task。由於scheduleMicrotask()方法的調用自身就處於一個Task,執行完當前的task,也就意味着立刻執行該Microtask。
瞭解了其工做機制,再來看看這4個Task Runner的具體工做內容。
Flutter引擎啓動會建立Dart虛擬機以及Root Isolate。DartVM自身也擁有本身的Isolate,徹底由虛擬機本身管理的,Flutter引擎也沒法直接訪問。Dart的UI相關操做,是由Root Isolate經過Dart的C++調用,或者是發送消息通知的方式,將UI渲染相關的任務提交到UIRunner執行,這樣就能夠跟Flutter引擎相關模塊進行交互。
何爲Isolate,從字面上理解是「隔離」,isolate之間是邏輯隔離的。Isolate中的代碼也是按順序執行,由於Dart沒有共享內存的併發,沒有競爭的可能性,故不須要加鎖,也沒有死鎖風險。對於Dart程序的併發則須要依賴多個isolate來實現。
圖解:
Flutter引擎啓動後執行Dart業務,是經過runApp(Widget app)方法,那Widget又是什麼呢?
Widget是全部Flutter應用程序的基石,Widget能夠是一個按鈕,一種字體或者顏色,一個佈局屬性等,在Flutter的UI世界可謂是「萬物皆Widget」。常見的Widget子類爲StatelessWidget(無狀態)和StatefulWidget(有狀態);
三棵樹
圖解:
可見,開發者經過Widget配置,Framework經過比對Widget配置來更新Element,最後調度RenderObject Tree完成佈局排列和繪製。
Dart的UI採用Widget來實現,最終轉換爲RenderObject,那界面又是如何渲染的呢?
渲染過程,UI線程完成佈局、繪製操做,生成Layer Tree;GPU線程執行合成並光柵化後交給GPU來處理,其中幾個關鍵步驟:
GPU線程經過skia向GPU硬件繪製一幀的數據,GPU將幀信息保存到FrameBuffer裏面,而後視頻控制器會根據VSync信號從FrameBuffer取幀數據傳遞給顯示器,從而顯示出最終的畫面。
Flutter框架提供了UI的控件支持,對於APP除了UI還有其餘依賴於Native平臺的支持,好比調用Camera的功能,該怎麼辦呢?爲此,Flutter經過提供Platform Channel的功能,使得Dart代碼具有與Native交互的能力。
Platform Channel用於Flutter與Native之間的消息傳遞,整個過程的消息與響應是異步執行,不會阻塞用戶界面。Flutter引擎框架已完成橋接的通道,這樣開發者只需在Native層編寫定製的Android/iOS代碼,便可在Dart代碼中直接調用,這也就是Flutter Plugin插件的一種形式。
科技不斷在進步,技術不斷髮展,移動跨平臺技術幾乎從Android、iOS誕生不久便出現,已發展快10年。時至今日,兼具跨端高效率與高性能體驗的Flutter力壓羣雄,嶄露頭角,已然成爲當下最熱門的移動端新技術,全球愈來愈多的公司在Flutter技術佈局並落地產品應用,社區也很是活躍。
筆者Gityuan以前一直從事於Android操做系統底層研發工做,今年剛接觸Flutter,Flutter做爲一門全新的跨平臺技術框架,不斷深究會發現這是一個小型系統,涉及到的技術很廣:
這些疑問本文都逐一解讀,若是僅僅是用Flutter作業務開發,並不須要掌握這麼深度技術,不過,知其然知其因此然,能讓你遊刃有餘。本文講述跨平臺技術的過去與將來,以及從宏觀架構解讀Flutter內部原理,後續有時間將更深刻的技術細節以及實戰經驗角度來跟你們揭祕更多Flutter技術。
隨着5G+IOT時代的到來,Fuchsia系統或許發力IOT新戰場,你所掌握的Flutter技術棧能夠無縫遷移,這是一次彎道超車的機會。即使Fuchsia落敗,相信只要深扎Flutter系統技術的精髓,其餘任何的移動端新技術均可以輕鬆快速地掌握。
最後,用一句話來結束本次分享,「有時候,你選擇一個方向,不是由於它必定會成爲將來,而是它有可能成爲不同的將來。」