首頁>技術>

Flutter 官方在 GitHub 上宣告是暫時不支援熱更新的,但是在 Flutter 的原始碼裡,是有一部分預埋的熱更新相關的程式碼,並且通過一些我們自己的手段,在Android端是能夠實現動態更新的功能的。

Flutter 產物的探究

不論是建立完全的 Flutter專案,還是 Native以 Moudle得方式整合 Flutter,亦或是 Native以 aar方式整合 Flutter,最終 Flutter在 Andorid端的 App 都是以 Native專案+ Flutter 的UI產物存在的。所以在這裡拆開一個 Flutter在 release模式下編譯後生成 aar包來做分析:

我們關注重點在 assets,jni,libs 這 3 個目錄中,其他的檔案都是 Nactive層殼工程的產物。

jni :該目錄下存在檔案 libflutter.so,該檔案為 Flutter Engine (引擎) 層的 C++實現,提供skia(繪製引擎),Dart,Text(紋理繪製)等支援;

libs:該目錄下存在檔案為 flutter.jar,該檔案為 Flutter embedding (嵌入) 層的 Java實現,該層提供給 Flutter 許多Native層平臺系統功能的支援,比如建立執行緒。

assets:該目錄下分為兩部分:

flutter_assets 目錄:該目錄下存放Flutter 我們應用層的資源,包括images,font等isolate_snapshot_data,isolate_snapshot_instr,vm_snapshot_data,vm_snapshot_instr 檔案:這 4 個檔案分別對應 isolate、VM 的資料段和指令段檔案,這就是我們自己的 Flutter 程式碼的產物了。Flutter 程式碼的熱更新

程式碼探究:

在我們的 Native 專案中,會在 FlutterMainActivity 中,通過呼叫 Flutter 這個類來建立 View:

檢視 Flutter 類程式碼,發現 Flutter 類主要做了幾件事:

在 startInitialization 中,主要執行了三個初始化方法 initConfig(applicationContext),initAot(applicationContext),initResources(applicationContext),最後記錄了執行時間。

在 initConfig 中:

在 initResources 中:

在 ResourceExtractor 類中,通過名字就能知道這個類是做資源提取的。把 add 的 Flutter 相關檔案從 assets 目錄中取出來,該類中 ExtractTask 的 doInBackground 方法中:

File dataDir = new File(PathUtils.getDataDirectory(ResourceExtractor.this.mContext))

如圖,可以看到該目錄是的訪問許可權是可讀可寫,所以理論上,我們只要把自己的 Flutter 產物下載後,從記憶體 copy 到這裡,便能夠實現程式碼的動態更新。

完整的程式碼實現:

Flutter 資源的熱更新

我們的App安裝到手機上後,是很難再修改 Assets 目錄下的資源,所以關於資源的替換,目前的方案是使用 Flutter 的 API :Image.file() 來從儲存卡中讀取圖片。

通常我們的 Flutter 專案中應當存有關於 App 的圖片,儘量保證在熱更新的時候使用已經存在的圖片。

其次,我們可以使用 Image.network() 來載入網路資源的圖片,如果還不能滿足需求,兜底的方案就是使用 Image.file(),將資源圖片放到Zip目錄下一起下發,並在Flutter程式碼中使用 Image.file() 來載入。

通過 Native 層方法拿到圖片資料夾的記憶體地址 dataDir判斷圖片是否存在,存在則載入,不存在則載入已經存在的圖片佔位

new File(dataDir + 'hotupdate_test.png').existsSync()? Image.file(new File(dataDir + 'hotupdate_test.png')): Image.asset("images/net_error.png"),

總結

在 Flutter 程式碼產物替換中,因為替換的 4 個檔案皆為直接載入到記憶體中的引擎程式碼,所以這部分優化空間有限。但在資源的熱更新中,資源是從Assets取得,所以這裡應該有更優的方案。

Flutter 的熱更新意味著可以在在App的一個入口裡,像 H5 一樣無窮的嵌入頁面,但又有和原生媲美的流暢體驗。

未來 Flutter 熱更新技術如果成熟,應用開發可能只需要 Android端和 IOS端實現本地業務功能模組的封裝,業務和UI的程式碼都放在 Flutter 中,便能夠真正的實現移動兩端一份業務程式碼,並且賦予產品在不影響使用者體驗的情況下,擁有動態部署APP內容的能力。

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 初學web前端程式設計師:從jQuery到Vue.js,程式設計思維怎樣轉換?