Tinker Flutter热修复

原理

在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'

##插件效果

Hook

注意

本Demo只做测试用,生产环境使用,还需要根据源码按自己需求修改。

比如:hookflutter库里面根据自己需求加载不同abi下的libapp.so 。 Flutter初始化只Hook了一个startInitialization 。 等等

下发补丁

Before

After

 

Tinker针对Flutter热修复需要的插件,GitHub地址TinkerForFlutter

posted @ 2020-08-18 19:41  狂奔的小狮子  阅读(1906)  评论(0编辑  收藏  举报