Github地址 Flutter熱更新demo
背景
Google從效能和安全兩方面考慮,暫時不會推出熱更新,把這個功能交給使用者和第三方去處理。結合公司不願提供任何資源,只能走捷徑的方式使用Tinker去實現Flutter的熱更新。
分析
Native專案可以接入Tinker進行熱更新,而且有Bugly做為補丁版本控制檯,來上傳下發補丁,統計數量,不需要再去實現,省了不少事。
接入Flutter模組,修改Dart程式碼後,執行buildTinkerPatchRelease,生成patch_signed_7zip.apk補丁包,解開patch_signed_7zip.apk,裡面也生成了Flutter模組的補丁so包。測試直接使用Tinker進行熱更新,Dart程式碼的修改並未生效。
由於Flutter有自己的一套so載入流程,Tinker無法載入到Flutter的補丁so包。分析下Flutter的so載入流程,在FlutterLoader類裡可以通過反射欄位aotSharedLibraryName把它set進去,這樣就可以實現載入補丁so檔案,測試Dart程式碼的修改生效。
但是在整合FlutterBoost後,這樣就行不通了。因為Flutter的初始化封裝在FlutterBoost類裡,FlutterBoost裡又new了一個FlutterEngine引擎類,傳入一個空字元陣列的FlutterShellArgs。需要我們把反射方法放在裡面的FlutterMain.startInitialization(mPlatform.getApplication());
方法後執行,或者把補丁so包路徑傳進來,add到flutterShellArgs裡。前一種方法需要反射,效能會有損耗,後一種雖然沒什麼損耗,只是需要把路徑層層傳進來,改動有點大。不過FlutterBoost做為模組依賴進來,改動一下也是可以的,測試生效。
結論
整個修復過程,都是利用Flutter自身載入so檔案去實現,所以不會出現相容性和安全性的問題,而且也不會對系統效能有任何大的損耗。同時,Tinker開源,可以方便的查閱Tinker的原始碼。
demo執行
down下來後,先開啟flutterhotfixmodule專案,open->HotFixFlutter->flutterhotfixmodule,開啟pubspec.yaml,點選Pub get,執行完成。再開啟HotFixFlutter,切換到Project下,等待Gradle Sync完成。再把FlutterBoost.instance().init(platform, FlutterPatch.getLibPath(this));
的引數給傳進createEngine(String libPath)
方法內,在裡面把
if (!TextUtils.isEmpty(libPath)) {
flutterShellArgs.add("--aot-shared-library-name=" + libPath);
flutterShellArgs.add("--aot-shared-library-name="
+ getApplicationInfo(mPlatform.getApplication().getApplicationContext()).nativeLibraryDir
+ File.separator + libPath);
}
複製程式碼
更新
未考慮到多人協同開發,下載FlutterBoost都要手動把路徑傳進去,不太方便。所以改為插樁到
FlutterMain.startInitialization(mPlatform.getApplication());
方法後實現,加入hannibal插樁庫,根配置新增
repositories下
maven { url 'https://dl.bintray.com/magicbaby/maven' }
複製程式碼
dependencies下
classpath 'com.sk.hannibal:hannibal:1.0.1.2'
複製程式碼
在app gradle裡配置
apply plugin: 'hannibal'
hannibal {
adjustFlutterBoost = true
insertClassFullName = 'com.xxx.xxxxx.FlutterPatch'
}
複製程式碼
自己的專案可以照著這個配置來,有什麼問題可以提issue