Flutter热更新技术探索

2023-09-22 09:45:00

一,需求背景:

APP发布到市场后,难免会遇到严重的BUG阻碍用户使用,因此有在不发布新版本APP的情况下使用热更新技术立即修复BUG需求。原生APP(例如:Android & IOS)的热更新需求已经比较成熟,但Flutter技术栈目前还缺少类似的技术方案,因此Flutter研发团队,也需要类似的热更新技术。

二,Flutter热更新技术方向分析:

经过分析目前可能有三种可行的方案: 1)类似RN框架; 2)页面动态组件框架; 3)Dart虚拟机定制方案;

方案名称原理优点缺点开源方案
类似RN的方案用JS以Flutter语法写dart,然后用JavaScript把XML DSL转为Flutter的原子widget组件,然后再让Flutter来渲染由于ios系统内置支持js,ios上完全可以实现更新1)由于跨语言执行,对于性能有影响;学习成本高 2)Android 端需要额外引入JS库手Q的MXFlutter,58同城的Fair
页面动态组件方案编译期时插桩/预埋好DynamicWidget到代码中,然后动态下发Json 数据,通过协定好的语义匹配到JSON内的数据,动态替换Widget内容来实现更新能支持Android/iOS 两端的更新1)UI更新相对较容易,业务逻辑动态化较麻烦; 2)语义解析器开发成本相对较大,且不易维护 3)需要一整套前后端服务和工具天猫的Tangram,淘宝的DinamicX等
Dart虚拟机定制方案通过分析Dart虚拟机的原理,修改Flutter Engine层Java/C++代码实现热更新的目标;性能影响小,动态性很高,技术上可以替换所有Flutter页面(包括UI,逻辑,资源文件)由于使用的是定制引擎,需要维护不同版本的Flutter引擎代码;未开源

因为其他方式都有开源的示例,本案将重点以第三种“Dart虚拟机定制方案”为目标,做方案的研究讲解。

三,预备知识

在开始了解技术方案之前,需要提前了解一些相应的技术概念:

3.1 Flutter编译模式

Flutter开发语言是Dart,它的编译模式来自Dart的编译模式,主要有JIT(Just In Time)和AOT(Ahead Of Time)。

编译模式名称特点优点缺点
JIT即时编译,典型例子V8,它可以即时编译运行JS,只需要输入源代码字符串,就可以编译运行代码可以动态下发和执行代码,不用管CPU架构,可以提供动态化内容1,大量字符串代码让JIT编译器花费时间和内存; 2,性能不好;
AOT预先编译,典型例子C/C++,通过GCC编译成二进制代码,然后安装取得权限后才可以加载执行事先编译好的,加载和执行速度快1,编译时区分CPU架构; 2,生成的二进制代码包比较大; 3,二进制代码需要取得权限才可以执行,无法在ios系统上动态更新

Flutter编译模式有:Debug,Release,Profile;

Flutter编译模式特点
Debug对应JIT模式,支持设备和模拟器; 打开了断言,支持快速开发,支持HotReload; 并未对包大小,执行速度做优化;
Release对应AOT模式,支持真机,不支持模拟器; 禁止了所有断言调试信息; 对包大小,启动和执行速度进行了优化;
Profile类似Release模式,保留了一些调试功能,帮助性能分析;

3.2 Flutter编译产物分析

Flutter下的iOS/Android工程本质上是一个标准的iOS/Android的工程;IOS平台: Flutter通过在BuildPhase中添加shell(xcode_backend.sh)来生成和嵌入App.framework和Flutter.framework到ios; Android平台: Flutter通过gradle来添加flutter.jar和编译完的二进制文件添加到Android;

3.2.1 引擎层结构分析:

3.2.2 Android编译产物的分析

3.2.3 IOS编译产物的分析

四,热更新技术方案分析

4.1 业务代码分析

根据“3.3.1” ~“3.3.2”的分析可以确定无论是IOS还是Android APP业务代码都是由四个段组成:kDartVmSnapshotData、kDartVmSnapshotInstructions、kDartIsolateSnapshotData、kDartIsolateSnapshotInstructions;理论上只要能动态替换加载的代码段&数据段代码即可实现目标。

名称注释作用注释
kDartIsolateSnapshotDataDart isolate数据段类信息,全局变量,函数指针等允许动态下发
kDartIsolateSnapshotInstructionsDart isolate指令段包含由Dart isolate执行的AOT代码IOS不允许动态下发
kDartVmSnapshotDatavm isolate数据段isolate 之间共享的 Dart 堆 (heap) 的初始状态允许动态下发
kDartVmSnapshotInstructionsvm isolate指令段包含 VM 中所有 Dart isolate 之间共享的通用程序的 AOT 指令IOS不允许动态下发

注释: isolate, snapshot, vm isolate含义解释如下:

名称含义
isolateDart是单线程,isolate跟线程差不多,可以理解为 Dart 中的线程。 isolate 与线程的区别:线程与线程之间是共享内存的,而 isolate 和 isolate 之间是内存不共享的。 不存在锁竞争问题,两个Isolate完全是两条独立的执行线,且每个Isolate都有自己的事件循环,它们之间只能通过发送消息通信,所以它的资源开销低于线程。
snapshot将类信息、全局变量、函数指令直接以序列化的方式存在磁盘中,称为 Snapshot(快照)。
vm isolate同一个进程里可以有很多isolate,但两个 isolate 的堆区是不能共享的,所以官方设计了 VM isolate,也就是 kDartVmSnapshot,用来多个 isolate 之间的交互。

4.2 业务代码的加载分析(运行时)

按照4.1的分析思路,我们首先需要了解Flutter运行时代码加载的完整流程,经过梳理分析流程如下:

1 )Android- APP业务代码的加载流程:

2)IOS- APP业务代码的加载流程:

4.3 业务代码的编译生成(编译时)

根据以上的分析,我们知道了Flutter业务代码的数据结构,也知道了在运行时如何加载,因此我们只需要在编译时做更改,产生自己需要的代码段,和数据段文件。在运行时加载自己的构建产物即可达到目标。

1)在此以 IOS 构建自己的业务代码流程做详细分析:

**有完成构建流程可以分析,基本流程是“Dart Code(业务代码)” -> (通过Dart编译器gen_snapshot.cc) 生成 snapshot_assemble.S 的汇编文件 -> (通过xcrun工具)生成 snapshot_assemble.o的obj文件 -> (通过xcun clang工具链) 生成了 App.Framework。

2)Android的产物构建流程和IOS类似。由于Android有其他更简单的方案, 因此省略详细的构建流程分析,大致如下:

4.4 实现热更新的方案探索

根据上面的技术分析结果,已经可以独立生成自己的代码段,数据段文件。通过需改虚拟机底层代码的方式,也可以动态的加载运行。但由于IOS系统目前底层的系统还不能动态加载可读写的代码段数据到内存中,所以还有技术难点需要突破。但Android端有更简单的路径可以解决,因此下面以Android端为例重点分析思路,大致如下图所示:

由上图可以得知,Android端 热修复核心步骤如下:

1, 修改Flutter Engine代码,加载指定路径的libapp.so和flutter_aasets,比如私有目录(data/data/files);

2, 编译APK时,利用Gradle Transform插件,根据Flutter SDK的engine version动态替换官方的Flutter engine,最终写入修改后的engine到APK;

3, 生成补丁包:利用BSdiff算法比较新旧APK文件,生成patch补丁包

4, APP启动时访问后端接口,根据参数(app的版本号,补丁包版本号,md5,flutter SDK版本号,Engine版本号)拉取补丁包;

5, 合成补丁包:校验md5,app版本号,补丁版本号,安装时间;

6, 自定义Flutter Engine加载指定路径的libapp.so和flutter_assets资源文件; 

更多推荐

form组件的封装(element ui ) 简单版本

当你使用Vue.js构建Web应用时,封装可复用组件是提高开发效率和代码可维护性的关键之一。在这篇文章中,我们将探讨如何使用Vue.js来创建一个通用的表单组件,以及如何将它封装成一个可配置的组件。实现思路拿下表单模板一个个的改造(文本,下拉,单选,复选等)按钮默认值的设定rules规则的处理创建通用的form组件这段

Arm机密计算架构技术(Armv9 CCA) 白皮书

1.概述在本篇文章中,我们将介绍机密计算(ConfidentialComputing)在现代计算平台中扮演的角色,并解释机密计算的原理。然后我们将说明Arm机密计算架构(ArmCCA)如何在Arm计算平台中实现机密计算。看完本文后,您将能够:定义机密计算描述复杂的系统信任链了解Realm(机密领域)是由ArmCCA引入

网络安全进阶学习第十八课——业务逻辑漏洞(附录:不同行业业务逻辑的漏洞)

文章目录一、互联网行业二、P2P金融行业三、电商行业四、政务行业总结一、互联网行业通用业务模块业务逻辑漏洞登录暴力破解用户名密码撞库验证码爆破和绕过、手机号撞库、账户权限绕过注册恶意用户批量注册、恶意验证注册账户、存储型XSS密码找回重置任意用户账户密码、批量重置用户密码、新密码劫持、短信验证码劫持、用户邮箱劫持篡改后

leetcode 1921. 消灭怪物的最大数量(每日一题)

最近学习的状态找回很多。慢慢来吧,加油!1921.消灭怪物的最大数量你正在玩一款电子游戏,在游戏中你需要保护城市免受怪物侵袭。给你一个下标从0开始且长度为n的整数数组dist,其中dist[i]是第i个怪物与城市的初始距离(单位:米)。怪物以恒定的速度走向城市。给你一个长度为n的整数数组speed表示每个怪物的速度,其

2023年中国研究生数学建模竞赛D题解题思路

为了更好的帮助大家第一天选题,这里首先为大家带来D题解题思路,分析对应赛题之后做题阶段可能会遇到的各种难点。稍后会带来D题的详细解析思路,以及相关的其他版本解题思路成品论文等资料。赛题难度评估:A、B>C>E、F>D选题人数评估:D>E、F>C>A、BD题区域双碳目标与路径规划研究以当下热门话题双碳碳中和为命题背景设置

孙哥Spring源码第24集

第24集处理AOP【视频来源于:B站up主孙帅sunsSpring源码视频】【微信号:suns45】1、谈一下你对ApplicationContext的理解BeanFactoryPostProcessorsBeanPostProcessor1.BDBeanFactoryPostProcessors、BeanPostPr

专利申请流程详解

专利申请的流程1、实用新型专利:是指对产品的形状、构造或者其结合所提出的适于实用的新的技术方案,指对有具体产品结构提出的改进或创造。与发明相比,实用新型专利申请对于技术的要求更低一点,在审查的时候不会进行详细的检索和对比,授权时间快,但实用新型的保护力度与发明专利的保护力度是不一样的。所需材料:请求书、说明书、权利要求

在内网部署docker工程总结

前言本次部署的内容主要包括:mysql,redis,nacos,java项目,前端项目,python项目。一安装docker环境首先在拥有网络环境的电脑上下载docker安装包,下载地址可以参考如下:https://download.docker.com/linux/static/stable/x86_64/下载完成之

RapidSSL的便宜单域名https证书

RapidSSL是Geotrusthttps证书品牌中的一款入门级https证书品牌,目前属于Digicert的子品牌。它是一款提供高性价比和广泛适用范围的https证书,无论是个人还是企业用户都可以轻松申请并快速验证。今天就随SSL盾小编了解RapidSSL旗下的单域名https证书。1.RapidSSL旗下的单域名

百望云亮相服贸会 重磅发布业财税融Copilot

小望小望,我要一杯拿铁!好的,已下单成功,请问要开具发票嘛?在获得确认的指令后,百小望AI智能助手按用户要求成功开具了一张电子发票!这是2023年服贸会国家会议中心·成果发布现场,百望云向与会嘉宾展示的业财税融Copilot产品的一个应用场景:在对接百望云后,咖啡师只需专注地制作咖啡,百小望AI智能助手即能完成接单、支

【深入浅出设计模式--命令模式】

深入浅出设计模式--命令模式一、背景二、问题三、解决方案四、试用场景总结五、后记一、背景命令模式是一种行为设计模式,它可以将用户的命令请求转化为一个包含有相关参数信息的对象,命令的发送者不需要知道接收者是如何处理这条命令,多个功能入口可以发送同一命令,避免多处多次实现相同功能的冗余代码。另外可以对命令进行延迟处理,或放

热文推荐