原理
在Android里面,Flutter打包之后的產物是一個.so文件(libapp.so),Tinker熱更新支持so文件更新,自然也就支持Flutter熱更新。 理論上這樣就可行了,不需要我們額外處理,但是Flutter初始化加載libapp.so時候,不去加載Tinker下載的補丁so,需要我們在初始化時候手動傳入下。
正常在初始化時候,用FlutterShellArgs把so路徑當參數傳入即可,或者用反射傳入也一樣,都能實現熱修復的效果。
可以這樣處理:
初始化傳參方式:
FlutterShellArgs flutterShellArgs = new FlutterShellArgs(new String[0]);
//libPath 就是libapp.so Tinker 下載補丁本地路徑
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);
}
FlutterMain.ensureInitializationComplete(
mPlatform.getApplication().getApplicationContext(), flutterShellArgs.toArray());
反射的方式:
try {
Field field = FlutterMain.class.getDeclaredField("sAotSharedLibraryName");
field.setAccessible(true);
field.set(null, libPath);
} catch (Exception e) {
e.printStackTrace();
}
那么問題來了,既然上面手動實現就幾行代碼就能實現了,為啥還要用插件實現呢?
1.插件實現可以和Flutter解耦,不需要侵入項目。
2.由於FlutterBoost的存在,很多人都在使用它,並不能直接修改Flutter的初始化流程,需要修改源碼。
插件就可以把兩者統一了。
可以寫個插件實現。
使用
根目錄build.gradle引入插件
classpath 'me.chunsheng:tinker4flutter:0.0.2'
app目錄build.gradle使用插件
apply plugin: 'tinker-for-flutter'
添加依賴庫:
implementation 'me.chunsheng:hookflutter:0.0.2'
##插件效果
注意
本Demo只做測試用,生產環境使用,還需要根據源碼按自己需求修改。
比如:hookflutter庫里面根據自己需求加載不同abi下的libapp.so 。 Flutter初始化只Hook了一個startInitialization 。 等等
下發補丁
Tinker針對Flutter熱修復需要的插件,GitHub地址TinkerForFlutter。