<address id="r9vd9"><address id="r9vd9"><listing id="r9vd9"></listing></address></address>

      歡迎您光臨深圳塔燈網絡科技有限公司!
      電話圖標 余先生:13699882642

      網站百科

      為您解碼網站建設的點點滴滴

      Flutter Hot Reload揭秘

      發表日期:2018-10 文章編輯:小燈 瀏覽次數:1528

      作者:閑魚技術-君愛

      1. 前言

      閑魚技術團隊在2018年引入Flutter,目前越來越多的業務場景在Flutter上使用。Flutter的亞秒級熱重載一直是開發者的神兵利器,提供給開發者快速修改UI,增加功能,修復bug,不需要重新啟動應用,即可看到改動效果。

      熱重載(HotReload)到底是如何實現的呢?

      本文帶你一步步揭開Hot Reload神秘面紗。

      2. 源碼分析

      2.1 FlutterTools調試

      想了解HotReload如何運行,首先,我們需要掌握flutter_tools的調試方法。

      我們創建一個名為fluttertest的簡單flutter項目作為例子。

      <img src='http://gw.alicdn.com/mt/TB1Fu3biCzqK1RjSZFpXXakSXXa-1820-798.png' width='80%'></img>

      使用AndroidStudio打開flutter_tools(/flutter/packages/flutter_tools),斷點設置為HotRunner.restart()方法

      <img src='http://gw.alicdn.com/mt/LB1op__iCzqK1RjSZPcXXbTepXa-2532-1576.jpg' width='80%'></img>

      添加新的Debug Configurations,woking directory設置為fluttertest項目地址

      <img src='http://gw.alicdn.com/mt/TB1yXZbiwTqK1RjSZPhXXXfOFXa-2142-1446.jpg' width='80%'></img>

      觸發flutter_tools debug按鈕,待app啟動后,簡單改動fluttertest代碼

      <img src='http://gw.alicdn.com/mt/TB1PtwbipzqK1RjSZFvXXcB7VXa-1884-820.png' width='80%'></img>

      在flutter_tools Debug Console中輸入r,開始調試。

      <img src='http://gw.alicdn.com/mt/LB1rHIsixYaK1RjSZFnXXa80pXa-2532-1576.jpg' width='80%'></img>

      斷點成功!

      2.1 HotReload基本流程

      那么HotReload如何運行呢?

      當我們使用運行HotReload,無論是通過控制臺輸入r啟動,或是點擊閃電運行,最終是運行flutter_tools中的HotRunner.restart(fullRestart: false)方法(上文斷點處)。

      restart()方法中,調用了_reloadSources(pause: pauseAfterRestart),正是HotReload的主要代碼之處。

      (源碼位于/flutter/packages/flutter_tools/lib/src/run_hot.dart)

      Future<OperationResult> _reloadSources({ bool pause = false }) 

      <img src='http://gw.alicdn.com/mt/TB1Qe3hisfpK1RjSZFOXXa6nFXa-895-477.png' width='80%'></img>

      _reloadSources方法中:

      1. 首先_updateDevFS()會將工程中文件逐一掃描,檢查是否有刪除、新增或者改動,掃描完成后,生成kernel files,命名為app.dill.incremental.dill文件,通過HTTP端口發送給DartVM;
      2. 將掃描生成的.dill文件路徑,通過RPC接口調用_reloadSources,進行資源加載;
      3. 確認VM資源重載成功,將FlutterDevice UI線程重置,通過RPC接口,觸發flutter widgets樹重建、重繪

      理解這個流程,前提需要明確Flutter的編譯模式。

      編譯模式大體可以分為兩種,AOT編譯與JIT編譯。JIT全稱是Just In Time,代碼可以在程序執行時期編譯,因為要在程序執行前進行分析、編譯,JIT編譯可能會導致程序執行時間較慢;而AOT編譯,全稱Ahead Of Time,是在程序運行前就已經編譯,從開發者修改代碼、編譯較慢,但運行時不需要進行分析、編譯,因此執行速度更快。

      Flutter使用了獨特的編譯模式,開發階段下,使用Kernel Snapshot模式(對應JIT編譯),將dart代碼生成標記化的源代碼,運行時編譯,解釋執行;release階段,ios使用AOT編譯,編譯器將dart代碼生成匯編代碼,最終生成app.framwork,android使用了Core JIT編譯,dart轉化為二進制模式,在VM啟動前載入。

      因此,基于開發階段的Kernel Snapshot編譯模式下,我們可以得知Hot Reload掃描項目文件,將有改動的dart文件轉化為標記化源代碼kernel files,發送到正在運行的DartVM,DartVM替換資源,然后通知Flutter Framework重建、重新布局、重新繪制WidgetsTree,即可看到改動效果。

      到這里,我們已經了解HotReload基本運行流程,但app.dill.incremental.dill是怎樣的文件,又怎么和舊文件替換的呢?

      2.2 增量代碼掃描

      在啟動應用后,啟動HotReload之前,編譯成功后,項目目錄/fluttertest/build文件中,自動生成了app.dill文件。
      <img src='http://gw.alicdn.com/mt/TB1ivkdiwHqK1RjSZFPXXcwapXa-1374-592.jpg' width='100%'></img>
      通過strings命令解析,發現是標記化的源代碼。

      <img src='http://gw.alicdn.com/mt/TB16SZhiwHqK1RjSZFEXXcGMXXa-1134-772.jpg' width='80%'></img>

      (篇幅較長,只截取了一部分)

      同時,通過adb shell檢查,發現設備中/data/data/com.loommo.fluttertest/com.loommo.fluttertest/app_flutter/flutter_assets下,生成三個文件;
      <img src='http://gw.alicdn.com/mt/TB16ZEdizDpK1RjSZFrXXa78VXa-1188-82.jpg' width='80%'></img>

      其中,kernel_blob.bin通過strings命令解析,發現內容與app.dill一致;
      <img src='http://gw.alicdn.com/mt/TB1E5ofipzqK1RjSZFCXXbbxVXa-1616-850.jpg' width='80%'></img>

      首次啟動應用后,生成的業務代碼文件app.dill,在設備上體現為kernel_blob.bin;

      我們啟動HotReload,_updateDevFS()這一步驟執行完畢后,

      (源碼位于/flutter/packages/flutter_tools/lib/src/devfs.dart)

      Future<int> update({@required String mainPath,String target,AssetBundle bundle,DateTime firstBuildTime,bool bundleFirstUpload = false,bool bundleDirty = false,Set<String> fileFilter,@required ResidentCompiler generator,String dillOutputPath,bool fullRestart = false,String projectRootPath,@required String pathToReload,}) 

      檢查項目,可以發現項目目錄/fluttertest/build/下新增了app.dill.incremental.dill文件,通過strings命令解析后,發現正是我們所改動的文件。

      <img src='http://gw.alicdn.com/mt/TB1tgkgiCzqK1RjSZFjXXblCFXa-1374-738.png' width='80%'></img>

      同時,通過adb shell檢查,發現設備中/data/data/com.loommo.fluttertest/cache/fluttertestYAYDGJ/fluttertest/lib下,也增加了一個main.dart.incremental.dill
      ,通過strings命令解析。

      <img src='http://gw.alicdn.com/mt/TB1nR7fisbpK1RjSZFyXXX_qFXa-1370-732.png' width='80%'></img>

      果然,與app.dill.incremental.dill內容一致。

      而/data/data/com.loommo.fluttertest/com.loommo.fluttertest/app_flutter/flutter_assets/kernel_blob.bin 沒有改變。

      上文中可以知道Flutter Tools生成app.dill.incremental.dill文件后,通過RPC調用_reloadSources,實際觸發的是,Flutter Engine中DartVM Reload方法,該方法中,對.incremental.dill進行增量編譯。

      (源碼位于/engine/src/third_party/dart/runtime/vm/isolate_reload.cc)

      void IsolateReloadContext::Reload(bool force_reload,const char* root_script_url,const char* packages_url_) 

      有興趣的同學可以仔細閱讀源碼。

      2.3 WidgetsTree重建

      從上文我們可以知道,Hot reload將資源重載完成后,通知flutter framework,觸發widgets樹的重新建立、重新布局、重新繪制。

      那么,flutter是如何觸發widgets樹的重建呢?

      Flutter framework中BindingBase注冊了名為reassemble的Dart VM服務,用于外部與正在運行的Dart VM通信,能夠觸發根節點樹重建操作。

      服務觸發后,BindingBase.reassembleApplication-> WidgetsBinding. performReassemble -> BuildOwner.reassemble -> Element.reassemble 由根節點開始一步步實現widgets樹重建。

      (源碼位于/flutter/packages/flutter/lib/src/foundation/binding.dart)

      Future<Null> reassembleApplication() 

      <img src='http://gw.alicdn.com/mt/TB1bvcvixYaK1RjSZFnXXa80pXa-495-523.png' width='60%'></img>

      3. 結語

      Flutter不同于以往Native開發,廣受贊譽的,其一便是亞秒級熱重載,理解HotReload的原理,有助于輔助我們日常開發,更為后續動態化方案提供理論支持。

      加入閑魚,一起玩些“酷”的

      閑魚技術團隊是一只短小精悍的工程技術團隊。我們不僅關注于業務問題的有效解決,同時我們在推動打破技術棧分工限制(android/iOS/Html5/Server 編程模型和語言的統一)、計算機視覺技術在移動終端上的前沿實踐工作。作為閑魚技術團隊的軟件工程師,您有機會去展示您所有的才能和勇氣,在整個產品的演進和用戶問題解決中證明技術發展是改變生活方式的動力。
      簡歷投遞:guicai.gxy@alibaba-inc.com

      4. 參考文檔

      1. Dart VM服務協議
      2. 深入理解flutter的編譯原理與優化
      3. Using Hot Reload
      4. 上述使用到的源碼

      本頁內容由塔燈網絡科技有限公司通過網絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網頁中由涉嫌抄襲的內容,請及時與我們聯系,并提供相關證據,工作人員會在5工作日內聯系您,一經查實,本站立刻刪除侵權內容。本文鏈接:http://www.webpost.com.cn/18196.html
      相關APP開發
       八年  行業經驗

      多一份參考,總有益處

      聯系深圳網站公司塔燈網絡,免費獲得網站建設方案及報價

      咨詢相關問題或預約面談,可以通過以下方式與我們聯系

      業務熱線:余經理:13699882642

      Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

      国产成人精品综合在线观看