成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解flutter的編譯原理與優(yōu)化

codecook / 2891人閱讀

摘要:本文將以一個(gè)簡(jiǎn)單的為例,介紹下相關(guān)原理及定制與優(yōu)化。模式對(duì)應(yīng)了的模式,又稱檢查模式或者慢速模式。為快速啟動(dòng),快速執(zhí)行,包大小做了優(yōu)化。并不支持模擬器的原因在于,模擬器上的診斷并不代表真實(shí)的性能。因此本文主要討論因引入的構(gòu)建,運(yùn)行等原理。

摘要: 閑魚技術(shù)-正物 問題背景 對(duì)于開發(fā)者而言,什么是Flutter?它是用什么語言編寫的,包含哪幾部分,是如何被編譯,運(yùn)行到設(shè)備上的呢?Flutter如何做到Debug模式Hot Reload快速生效變更,Release模式原生體驗(yàn)的呢?Flutter工程和我們的Android/iOS工程有何差別,關(guān)...

閑魚技術(shù)-正物

問題背景

對(duì)于開發(fā)者而言,什么是Flutter?它是用什么語言編寫的,包含哪幾部分,是如何被編譯,運(yùn)行到設(shè)備上的呢?Flutter如何做到Debug模式Hot Reload快速生效變更,Release模式原生體驗(yàn)的呢?Flutter工程和我們的Android/iOS工程有何差別,關(guān)系如何,又是如何嵌入Android/iOS的呢?Flutter的渲染和事件傳遞機(jī)制如何工作?Flutter支持熱更新嗎?Flutter官方并未提供iOS下的armv7支持,確實(shí)如此嗎?在使用Flutter的時(shí)候,如果發(fā)現(xiàn)了engine的bug,如何去修改和生效?構(gòu)建緩慢或出錯(cuò)又如何去定位,修改和生效呢?

凡此種種,都需要對(duì)Flutter從設(shè)計(jì),開發(fā)構(gòu)建,到最終運(yùn)行有一個(gè)全局視角的觀察。

本文將以一個(gè)簡(jiǎn)單的hello_flutter為例,介紹下Flutter相關(guān)原理及定制與優(yōu)化。

Flutter簡(jiǎn)介

Flutter的架構(gòu)主要分成三層:Framework,Engine和Embedder。

Framework使用dart實(shí)現(xiàn),包括Material Design風(fēng)格的Widget,Cupertino(針對(duì)iOS)風(fēng)格的Widgets,文本/圖片/按鈕等基礎(chǔ)Widgets,渲染,動(dòng)畫,手勢(shì)等。此部分的核心代碼是:flutter倉庫下的flutter package,以及sky_engine倉庫下的io,async,ui(dart:ui庫提供了Flutter框架和引擎之間的接口)等package。

Engine使用C++實(shí)現(xiàn),主要包括:Skia,Dart和Text。Skia是開源的二維圖形庫,提供了適用于多種軟硬件平臺(tái)的通用API。其已作為Google Chrome,Chrome OS,Android, Mozilla Firefox, Firefox OS等其他眾多產(chǎn)品的圖形引擎,支持平臺(tái)還包括Windows7+,macOS 10.10.5+,iOS8+,Android4.1+,Ubuntu14.04+等。Dart部分主要包括:Dart Runtime,Garbage Collection(GC),如果是Debug模式的話,還包括JIT(Just In Time)支持。Release和Profile模式下,是AOT(Ahead Of Time)編譯成了原生的arm代碼,并不存在JIT部分。Text即文本渲染,其渲染層次如下:衍生自minikin的libtxt庫(用于字體選擇,分隔行)。HartBuzz用于字形選擇和成型。Skia作為渲染/GPU后端,在Android和Fuchsia上使用FreeType渲染,在iOS上使用CoreGraphics來渲染字體。

Embedder是一個(gè)嵌入層,即把Flutter嵌入到各個(gè)平臺(tái)上去,這里做的主要工作包括渲染Surface設(shè)置,線程設(shè)置,以及插件等。從這里可以看出,F(xiàn)lutter的平臺(tái)相關(guān)層很低,平臺(tái)(如iOS)只是提供一個(gè)畫布,剩余的所有渲染相關(guān)的邏輯都在Flutter內(nèi)部,這就使得它具有了很好的跨端一致性。

Flutter工程結(jié)構(gòu)
本文使用開發(fā)環(huán)境為flutter beta v0.3.1,對(duì)應(yīng)的engine commit:09d05a389。

以hello_flutter工程為例,F(xiàn)lutter工程結(jié)構(gòu)如下所示:

其中ios為iOS部分代碼,使用CocoaPods管理依賴,android為Android部分代碼,使用Gradle管理依賴,lib為dart代碼,使用pub管理依賴。類似iOS中Cocoapods對(duì)應(yīng)的Podfile和Podfile.lock,pub下則是pubspec.yaml和pubspec.lock。

Flutter模式

對(duì)于Flutter,它支持常見的debug,release,profile等模式,但它又有其不一樣。

Debug模式:對(duì)應(yīng)了Dart的JIT模式,又稱檢查模式或者慢速模式。支持設(shè)備,模擬器(iOS/Android),此模式下打開了斷言,包括所有的調(diào)試信息,服務(wù)擴(kuò)展和Observatory等調(diào)試輔助。此模式為快速開發(fā)和運(yùn)行做了優(yōu)化,但并未對(duì)執(zhí)行速度,包大小和部署做優(yōu)化。Debug模式下,編譯使用JIT技術(shù),支持廣受歡迎的亞秒級(jí)有狀態(tài)的hot reload。

Release模式:對(duì)應(yīng)了Dart的AOT模式,此模式目標(biāo)即為部署到終端用戶。只支持真機(jī),不包括模擬器。關(guān)閉了所有斷言,盡可能多地去掉了調(diào)試信息,關(guān)閉了所有調(diào)試工具。為快速啟動(dòng),快速執(zhí)行,包大小做了優(yōu)化。禁止了所有調(diào)試輔助手段,服務(wù)擴(kuò)展。

Profile模式:類似Release模式,只是多了對(duì)于Profile模式的服務(wù)擴(kuò)展的支持,支持跟蹤,以及最小化使用跟蹤信息需要的依賴,例如,observatory可以連接上進(jìn)程。Profile并不支持模擬器的原因在于,模擬器上的診斷并不代表真實(shí)的性能。

鑒于Profile同Release在編譯原理等上無差異,本文只討論Debug和Release模式。

事實(shí)上flutter下的iOS/Android工程本質(zhì)上依然是一個(gè)標(biāo)準(zhǔn)的iOS/Android的工程,flutter只是通過在BuildPhase中添加shell來生成和嵌入App.framework和Flutter.framework(iOS),通過gradle來添加flutter.jar和vm/isolate_snapshot_data/instr(Android)來將Flutter相關(guān)代碼編譯和嵌入原生App而已。因此本文主要討論因flutter引入的構(gòu)建,運(yùn)行等原理。編譯target雖然包括arm,x64,x86,arm64,但因原理類似,本文只討論arm相關(guān)(如無特殊說明,android默認(rèn)為armv7)。

Flutter代碼的編譯與運(yùn)行(iOS)
Release模式下的編譯
release模式下,flutter下iOS工程中dart代碼構(gòu)建鏈路如下所示:

其中g(shù)en_snapshot是dart編譯器,采用了tree shaking(類似依賴樹邏輯,可生成最小包,也因而在Flutter中禁止了dart支持的反射特性)等技術(shù),用于生成匯編形式的機(jī)器代碼,再通過xcrun等編譯工具鏈生成最終的App.framework。換句話說,所有的dart代碼,包括業(yè)務(wù)代碼,三方package代碼,它們所依賴的flutter框架代碼,最終將會(huì)變成App.framework。

tree shaking功能位于gen_snapshot中,對(duì)應(yīng)邏輯參見: engine/src/third_party/dart/runtime/vm/compiler/aot/precompiler.cc

dart代碼最終對(duì)應(yīng)到App.framework中的符號(hào)如下所示:

事實(shí)上,類似Android Release下的產(chǎn)物(見下文),App.framework也包含了kDartVmSnapshotData,kDartVmSnapshotInstructions,kDartIsolateSnapshotData,kDartIsolateSnapshotInstructions四個(gè)部分。為什么iOS使用App.framework這種方式,而不是Android的四個(gè)文件的方式呢?原因在于在iOS下,因?yàn)橄到y(tǒng)的限制,F(xiàn)lutter引擎不能夠在運(yùn)行時(shí)將某內(nèi)存頁標(biāo)記為可執(zhí)行,而Android是可以的。

Flutter.framework對(duì)應(yīng)了Flutter架構(gòu)中的engine部分,以及Embedder。實(shí)際中Flutter.framework位于flutter倉庫的/bin/cache/artifacts/engine/ios*下,默認(rèn)從google倉庫拉取。當(dāng)需要自定義修改的時(shí)候,可通過下載engine源碼,利用Ninja構(gòu)建系統(tǒng)來生成。

Flutter相關(guān)代碼的最終產(chǎn)物是:App.framework(dart代碼生成)和Flutter.framework(引擎)。從Xcode工程的視角看,Generated.xcconfig描述了Flutter相關(guān)環(huán)境的配置信息,然后Runner工程設(shè)置中的Build Phases新增的xcode_backend.sh實(shí)現(xiàn)了Flutter.framework的拷貝(從Flutter倉庫的引擎到Runner工程根目錄下的Flutter目錄)與嵌入和App.framework的編譯與嵌入。最終生成的Runner.app中Flutter相關(guān)內(nèi)容如下所示:

其中flutter_assets是相關(guān)的資源,代碼則是位于Frameworks下的App.framework和Flutter.framework。

Debug模式下的編譯
Debug模式下flutter的編譯,結(jié)構(gòu)類似Release模式,差異主要表現(xiàn)為兩點(diǎn):

1.Flutter.framework

因?yàn)槭荄ebug,此模式下Framework中是有JIT支持的,而在Release模式下并沒有JIT部分。

2.App.framework

不同于AOT模式下的App.framework是Dart代碼對(duì)應(yīng)的本地機(jī)器代碼,JIT模式下,App.framework只有幾個(gè)簡(jiǎn)單的API,其Dart代碼存在于snapshot_blob.bin文件里。這部分的snapshot是腳本快照,里面是簡(jiǎn)單的標(biāo)記化的源代碼。所有的注釋,空白字符都被移除,常量也被規(guī)范化,也沒有機(jī)器碼,tree shaking或者是混淆。

App.framework中的符號(hào)表如下所示:

對(duì)Runner.app/flutter_assets/snapshot_blob.bin執(zhí)行strings命令可以看到如下內(nèi)容:

Debug模式下main入口的調(diào)用堆棧如下:

debug isolate main callstack

Flutter代碼的編譯與運(yùn)行(Android)
鑒于Android和iOS除了部分平臺(tái)相關(guān)的特性外,其他邏輯如Release對(duì)應(yīng)AOT,Debug對(duì)應(yīng)JIT等均類似,此處只涉及兩者不同。

Release模式下的編譯
release模式下,flutter下Android工程中dart代碼整個(gè)構(gòu)建鏈路如下所示:

其中vm/isolate_snapshot_data/instr內(nèi)容均為arm指令,將會(huì)在運(yùn)行時(shí)被engine載入,并標(biāo)記vm/isolate_snapshot_instr為可執(zhí)行。vm_中涉及runtime等服務(wù)(如gc),用于初始化DartVM,調(diào)用入口見Dart_Initialize(dart_api.h)。isolate__則是對(duì)應(yīng)了我們的App代碼,用于創(chuàng)建一個(gè)新的isolate,調(diào)用入口見Dart_CreateIsolate(dart_api.h)。flutter.jar類似iOS的Flutter.framework,包括了engine部分的代碼(Flutter.jar中的libflutter.so),以及一套將Flutter嵌入Android的類和接口(FlutterMain,FlutterView,FlutterNativeView等)。實(shí)際中flutter.jar位于flutter倉庫的/bin/cache/artifacts/engine/android*下,默認(rèn)從google倉庫拉取。當(dāng)需要自定義修改的時(shí)候,可通過下載engine源碼,利用Ninja構(gòu)建系統(tǒng)來生成flutter.jar。

原文鏈接

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/25246.html

相關(guān)文章

  • Flutter 面試知識(shí)點(diǎn)集錦

    摘要:中的的線程是以事件循環(huán)和消息隊(duì)列的形式存在,包含兩個(gè)任務(wù)隊(duì)列,一個(gè)是內(nèi)部隊(duì)列,一個(gè)是外部隊(duì)列,而的優(yōu)先級(jí)又高于。同時(shí)還有處理按住時(shí)的事件額外處理,同時(shí)手勢(shì)處理一般在的子類進(jìn)行。谷歌大會(huì)之后,有不少人咨詢了我 Flutter 相關(guān)的問題,其中有不少是和面試相關(guān)的,如今一些招聘上也開始羅列 Flutter 相關(guān)要求,最后想了想還是寫一期總結(jié)吧,也算是 Flutter 的階段復(fù)習(xí)。 ??系統(tǒng)完...

    andong777 評(píng)論0 收藏0
  • 性能優(yōu)化全新思路!實(shí)踐騰訊、字節(jié)、阿里、百度、網(wǎng)易等互聯(lián)網(wǎng)公司項(xiàng)目實(shí)戰(zhàn)+案例分析(附PDF源碼)

    摘要:不努力不奮斗,可能就會(huì)在基層一輩子止步不前。不過,只一句,如果你還在做這一行,還是一名程序猿媛,想走上坡路的你,也許我這到手的十幾家一線互聯(lián)網(wǎng)公司性能優(yōu)化項(xiàng)目實(shí)戰(zhàn)可能會(huì)對(duì)你有所幫助。 ...

    ytwman 評(píng)論0 收藏0
  • Android程序員到底有多累,多辛苦?

    摘要:其實(shí),這種時(shí)候,需要做的是馬上買空氣凈化器,任何一款都好,哪怕是凈化能力差一點(diǎn)的,也能解決當(dāng)前的主要問題,更好的凈化器帶給你的凈化效果的提升,不過是多一點(diǎn)邊際收益。 前言 說到底,是自己的選擇問題。 三百六十行,哪行容易? 但關(guān)鍵是自己的心態(tài),如果工作成了你的負(fù)擔(dān)和困擾,你得有跳出來的...

    adam1q84 評(píng)論0 收藏0
  • Android程序員完全沒時(shí)間提升自己怎么辦?

    摘要:昨天有個(gè)小學(xué)弟給我發(fā)來微信,說他現(xiàn)在有點(diǎn)后悔選擇開發(fā)了,月月光不說,還加班特別嚴(yán)重,平時(shí)也沒有屬于自己的時(shí)間去學(xué)習(xí),問我剛畢業(yè)的時(shí)候是不是這樣。每天回到出租屋都是倒頭就睡,非常累,也沒有其他時(shí)間提升自己的技術(shù)。 昨天有個(gè)小學(xué)弟給我發(fā)來微信,說他現(xiàn)在有點(diǎn)后悔選擇Android開發(fā)了,月月光不說...

    kohoh_ 評(píng)論0 收藏0
  • 用前端 最舒服躺姿 "搞定" Flutter (組件篇)

    摘要:是谷歌的移動(dòng)框架,可以快速在和上構(gòu)建高質(zhì)量的原生用戶界面。在全世界好了這些,大家早就知道了,來點(diǎn)實(shí)在的話說隔壁師兄,閑魚是最早一批與谷歌展開合作,并在重要的商品詳情頁中使用技術(shù)上線的。一切皆來自的組件皆來自。是狀態(tài)不可變的稱為無狀態(tài)。 前言 要說2018年最火的跨端技術(shù),當(dāng)屬于 Flutter 莫屬,應(yīng)該沒人質(zhì)疑吧。一個(gè)新的技術(shù)的趨勢(shì),最明顯的特征,就是它一定想把前浪拍死在沙灘上。這個(gè)...

    LMou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<