美文网首页Flutter
flutter android动态化原理篇

flutter android动态化原理篇

作者: 面朝对象_春暖花开 | 来源:发表于2019-10-25 17:25 被阅读0次

    基于flutter1.5.4版本

    android动态化思路简介:

    目前flutter在android的动态化相对简单,无非是将一个apk作为基线文件,然后再生成一个apk并与基线文件bsdiff40查分算法,生成一个.zip文件作为patch包。此时我们将patch包放于服务器,并由客户端拉取,客户端拿到patch包再做一次bsdiff40的合成,最终达到动态化的目的。

    android动态化源码解析:

    1、android工程配置

    目的:需要告知flutterSDK我们需要动态化,以及动态化的方式。一共有三个配置,具体如下:

    • 1、DynamicPatching :允许flutter动态化
    <application>
        <meta-data
            android:name="DynamicPatching"
            android:value="true" />
    </application>
    
    • 2、PatchDownloadMode :下载patch的时机
    <application>
    // 可选:PatchDownloadMode = ON_RESTART(0,表示冷启)、ON_RESUME(1,表示热启)、默认为ON_RESTART 
        <meta-data
            android:name="PatchDownloadMode"
            android:value=0|1 />
    </application>
    
    • 3、PatchInstallMode :patch的生效时机
    <application>
    // 可选:PatchInstallMode = ON_NEXT_RESTART(0,表示下次)、IMMEDIATE(1,表示立刻)、默认为ON_NEXT_RESTART 
        <meta-data
            android:name="PatchInstallMode"
            android:value=0|1 />
    </application>
    

    2、生成patch文件

    1、首先生成基线文件

    首先需要添加如下配置:需要注意的是dynamicRelease需要写在release下面,否则会导致无法签名

    //app中加入该buildType
    dynamicRelease{
            initWith release
        }
    

    然后执行:
    flutter build apk --release --dynamic
    中途可能出现因为java版本问题导致失败,这里是因为flutter.gradle中使用java 1.8,解决方案如下:

    //在defaultConfig {}中添加
     jackOptions{
                enabled = true
            }
    

    不出问题的话,基线文件生成成功,在build/app/outputs/apk下面,如下:

    image.png
    flutter命令行生成apk,经过debug发现,真正的执行命令是gradlew,上面的flutter build apk --release --dynamic最终执行为:

    /Users/zhuyaning/Desktop/flutterDemo/abd/android/gradlew -q -Ptarget=lib/main.dart -Ptrack-widget-creation=false -Pcompilation-trace-file=compilation.txt -Ptarget-platform=android-arm assembleDynamicRelease

    assembleDynamicRelease也反证了刚刚为什么要在build.gradle添加dynamicRelease

    2、基线文件放置在指定目录下面,详情如下:

    在flutter主工程目录下面,也就是同时包含ios和android的目录下面创建.baseline文件夹,将app-dynamicRelease.apk重命名为1.apk放入.baseline文件夹中。

    • 为什么文件名为.baselineflutter_toolsbuild_apk.dart文件的addDynamicBaselineFlags方法定义的,可以按需求自我修改文件名及路径。
    • 为什么重命名为1.apk:代表基线包的版本

    3、根据基线包生成patch文件:

    flutter build apk --release --dynamic --patch

    这条命令最终执行的依然是gradlew

    /Users/zhuyaning/Desktop/flutterDemo/abd/android/gradlew -q -Ptarget=lib/main.dart -Ptrack-widget-creation=false -Pcompilation-trace-file=compilation.txt -Ppatch=true -Ptarget-platform=android-arm assembleDynamicRelease

    注:此命令依然是生成一个新的apk,然后与1.apk做的bsdiff算法,源码在flutter_tool工程下搜索_buildGradleProjectV2,所以我们可以安装自己公司的算法自己修改此处代码。

    最终patch被输出到Project/public目录下面:

    image.png

    3、patch的使用:

    我们得到patch生成之后,客户端是如何使用的?在flutter engine中我们得到答案:
    和动态化的代码在如下三个文件:
    FlutterMain.java
    ResourceExtractor.java
    ResourceUpdater.java

    入口在FlutterMain.startInitialization(context)中:

    if (metaData != null && metaData.getBoolean("DynamicPatching")) {
        sResourceUpdater = new ResourceUpdater(context);
        // Also checking for ON_RESUME here since it's more efficient than waiting for actual
        // onResume. Even though actual onResume is imminent when the app has just restarted,
        // it's better to start downloading now, in parallel with the rest of initialization,
        // and avoid a second application restart a bit later when actual onResume happens.
        if (sResourceUpdater.getDownloadMode() == ResourceUpdater.DownloadMode.ON_RESTART ||
            sResourceUpdater.getDownloadMode() == ResourceUpdater.DownloadMode.ON_RESUME) {
            sResourceUpdater.startUpdateDownloadOnce();
            if (sResourceUpdater.getInstallMode() == ResourceUpdater.InstallMode.IMMEDIATE) {
                sResourceUpdater.waitForDownloadCompletion();
            }
        }
    

    整体替换及更新思路,大家看完这三个文件就会明白。

    4、总结:

    目前的android动态化方案做的很糙:

    • patch缺少签名带来安全隐患
    • 版本控制
    • 下载patch的方案
    • 无法自定义更新方案、生效时机

    功能虽然很糙,但是公司可以根据自己需求开始自定义。

    flutter的广大爱好者们,我在微信创建了一个公众号,搜索flutter 干货、或微信扫一扫下面的二维码关注一下吧,平时会发一些flutter源码解读、技术点使用、平台化落地相关的干货,也是希望大家能把问题抛出来,让我也能研究一下,也希望能互相帮助。

    WechatIMG10.jpeg

    相关文章

      网友评论

        本文标题:flutter android动态化原理篇

        本文链接:https://www.haomeiwen.com/subject/rotevctx.html