首先來了解一下 JIT & AOT
JIT & AOT
JIT全稱是Just In Time
,代碼可以在程序執(zhí)行時期編譯,因為要在程序執(zhí)行前進行分析、編譯趁桃,JIT編譯可能會導(dǎo)致程序執(zhí)行時間較慢仑最;而AOT編譯扔役,全稱Ahead Of Time
,是在程序運行前就已經(jīng)編譯警医,從開發(fā)者修改代碼到編譯的過程較慢亿胸,但運行時不需要進行分析、編譯预皇,因此執(zhí)行速度更快侈玄。
Flutter使用了獨特的編譯模式,開發(fā)階段下吟温,使用Kernel Snapshot
模式(對應(yīng)JIT編譯)序仙,將dart代碼生成標記化的源代碼,運行時編譯鲁豪,解釋執(zhí)行潘悼;release階段,ios使用AOT編譯
呈昔,編譯器將dart代碼生成匯編代碼挥等,最終生成app.framwork,android使用了Core JIT編譯
堤尾,dart轉(zhuǎn)化為二進制模式肝劲,在VM啟動前載入。
hot reload 原理
Flutter通過將新的代碼注入到正在運行的DartVM中郭宝,來實現(xiàn)Hot Reload這種神奇的效果辞槐,在DartVM將程序中的類結(jié)構(gòu)更新完成后,F(xiàn)lutter會立即重建整個控件樹粘室,從而更新界面榄檬。
觸發(fā)熱刷新時Flutter會檢測發(fā)生改變的Dart文件,將其同步到App私有緩存目錄下衔统,DartVM加載并且修改對應(yīng)的類或者方法鹿榜,重建控件樹后立即可以在設(shè)備上看到效果。
熱刷新限制
并不是所有的代碼改動都可以通過熱刷新來更新:
編譯錯誤锦爵,如果修改后的Dart代碼無法通過編譯舱殿,F(xiàn)lutter會在控制臺報錯,這時需要修改對應(yīng)的代碼险掀。
控件類型從StatelessWidget到StatefulWidget的轉(zhuǎn)換沪袭,因為Flutter在執(zhí)行熱刷新時會保留程序原來的state,而某個控件從stageless→stateful后會導(dǎo)致Flutter重新創(chuàng)建控件時報錯“myWidget is not a subtype of StatelessWidget”樟氢,而從stateful→stateless會報錯“type 'myWidget' is not a subtype of type 'StatefulWidget' of 'newWidget'”冈绊。
全局變量和靜態(tài)成員變量侠鳄,這些變量不會在熱刷新時更新。
修改了main函數(shù)中創(chuàng)建的根控件節(jié)點死宣,F(xiàn)lutter在熱刷新后只會根據(jù)原來的根節(jié)點重新創(chuàng)建控件樹伟恶,不會修改根節(jié)點。
某個類從普通類型轉(zhuǎn)換成枚舉類型十电,或者類型的泛型參數(shù)列表變化知押,都會使熱刷新失敗叹螟。
熱刷新無法實現(xiàn)更新時鹃骂,執(zhí)行一次熱重啟(Hot Restart)就可以全量更新所有代碼,同樣不需要重啟App罢绽,區(qū)別是restart會將所有Dart代碼打包同步到設(shè)備上畏线,并且所有狀態(tài)都會重置