一文帶你弄懂Flutter的熱部署
關于Dart中的運行方式
- JIT:Just In Time . 動態解釋,一邊翻譯一邊執行,也稱為即時編譯,如JavaScript,Python等,在開發周期中使用,可以動態下發和執行代碼,開發測試效率高,但是運行速度和性能則會受到影響,Flutter中的熱重載正是基于此特性
- AOT: Ahead of Time. 靜態編譯,是指程序在執行前全部被翻譯為機器碼,提前編譯,如 C ,C++ ,OC等,發布時期使用AOT,就不需要像RN那樣在跨平臺JavaScript代碼和原生Android、iOS代碼間建立低效的方法調用映射關系。
程序的運行方式和具體的語言沒有強制關系,比如python,既可以是JIT 也可以是AOT,Dart是少數同時支持JIT和AOT的語言之一。
Dart在開發過程中使用JIT,每次更改都不需要在編譯成字節碼,節省了大量時間,在部署中使用AOT生成高效的ARM代碼保證高效的性能,所以說Dart具有運行速度快,執行性能好的特點。
Hot Reload
在Dart代碼文件中修改字符串“Hello, World”,添加一個驚嘆號,點擊保存或者熱刷新按鈕就可以立即更新到界面上,僅需幾百毫秒:
Flutter通過將新的代碼注入到正在運行的DartVM中,來實現Hot Reload這種神奇的效果,在DartVM將程序中的類結構更新完成后,Flutter會立即重建整個控件樹,從而更新界面。但是熱刷新也有一些限制,并不是所有的代碼改動都可以通過熱刷新來更新:
- 編譯錯誤,如果修改后的Dart代碼無法通過編譯,Flutter會在控制臺報錯,這時需要修改對應的代碼。
- 控件類型從StatelessWidget到StatefulWidget的轉換,因為Flutter在執行熱刷新時會保留程序原來的state,而某個控件從stageless→stateful后會導致Flutter重新創建控件時報錯“myWidget is not a subtype of StatelessWidget”,而從stateful→stateless會報錯“type ‘myWidget’ is not a subtype of type ‘StatefulWidget’ of ‘newWidget’”。
- 全局變量和靜態成員變量,這些變量不會在熱刷新時更新。
- 修改了main函數中創建的根控件節點,Flutter在熱刷新后只會根據原來的根節點重新創建控件樹,不會修改根節點。
- 某個類從普通類型轉換成枚舉類型,或者類型的泛型參數列表變化,都會使熱刷新失敗。
熱刷新無法實現更新時,執行一次熱重啟(Hot Restart)就可以全量更新所有代碼,同樣不需要重啟App,區別是restart會將所有Dart代碼打包同步到設備上,并且所有狀態都會重置。