Flutter热更新技术探索
一,需求背景:
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;理论上只要能动态替换加载的代码段 & 数据段代码即可实现目标。
| 名称 | 注释 | 作用 | 注释 |
| kDartIsolateSnapshotData | Dart isolate 数据段 | 类信息,全局变量,函数指针等 | 允许动态下发 |
| kDartIsolateSnapshotInstructions | Dart isolate 指令段 | 包含由 Dart isolate 执行的 AOT 代码 | IOS 不允许动态下发 |
| kDartVmSnapshotData | vm isolate 数据段 | isolate 之间共享的 Dart 堆 (heap) 的初始状态 | 允许动态下发 |
| kDartVmSnapshotInstructions | vm isolate 指令段 | 包含 VM 中所有 Dart isolate 之间共享的通用程序的 AOT 指令 | IOS 不允许动态下发 |
注释:isolate, snapshot, vm isolate 含义解释如下:
| 名称 | 含义 |
| isolate | Dart 是单线程,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 资源文件;
相关文章:
Flutter热更新技术探索
一,需求背景: APP 发布到市场后,难免会遇到严重的 BUG 阻碍用户使用,因此有在不发布新版本 APP 的情况下使用热更新技术立即修复 BUG 需求。原生 APP(例如:Android & IOS)的热更新需求已经…...
【机器学习-00】机器学习是什么?
在科技飞速发展的今天,机器学习已成为一个热门话题,广泛应用于各个行业和领域。那么,机器学习到底是什么?它又是如何工作的?本文将深入探讨机器学习的定义、原理及其在各领域的应用,带领读者走进这个神秘而…...
【BUG】已解决:WslRegisterDistribution failed with error: 0x800701bc
已解决:WslRegisterDistribution failed with error: 0x800701bc 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武…...
无人机监测的必要性及方法
为什么需要无人机探测? 无人机的快速发展和广泛使用为各个行业带来了巨大好处,包括送货服务、农业和监控。然而,这种扩散也导致滥用现象增多,造成非法入侵空域、侵犯隐私和安全威胁。监控和探测在特定空域盘旋的无人机的能力变得…...
PHP框架详解:Symfony框架
Symfony是一个功能强大且高度灵活的PHP框架,广泛应用于企业级项目和复杂的Web应用开发。本文将详细介绍Symfony框架的主要特性,并通过实例展示其强大功能。 1. 什么是Symfony? Symfony是一个基于MVC(模型-视图-控制器࿰…...
在 Navicat BI 创建自定义字段:类型更改字段
早在 Navicat 17 的预览版中,我们就已经介绍了一些新的商业智能(BI)功能,即图表互动和计算字段。需要说明的是,计算字段不是 Navicat BI 中唯一可用的自定义字段类型。事实上,有五种:类型改变、…...
llama-index,uncharted and llama2:7b run locally to generate Index
题意:本地运行 llama-index、uncharted 以及 llama2:7b 来生成索引 问题背景: I wanted to use llama-index locally with ollama and llama3:8b to index utf-8 json file. I dont have a gpu. I use uncharted to convert docs into json. Now If it …...
vue、js截取视频任意一帧图片
html有本地上传替换部分,可以不看 原理:通过video标签对视频进行加载,随后使用canvas对截取的视频帧生成需要的图片 <template> <el-row :gutter"18" class"preview-video"><h4>视频预览<span&…...
STM32智能家居系统教程
目录 引言环境准备智能家居系统基础代码实现:实现智能家居系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景:家居智能化管理问题解决方案与优化收尾与总结 1. 引言 智能家居系统通过STM32嵌入…...
uniapp 开发 App 对接官方更新功能
插件地址:升级中心 uni-upgrade-center - App - DCloud 插件市场 首先创建一个 uni-admin 项目,选择你要部署的云开发服务商: 然后会自动下载模板,部署云数据库、云函数 第二步:将新创建的 uni-admin 项目托管到…...
【PostgreSQL】PostgreSQL 教程
博主介绍:✌全网粉丝20W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
Qt类 | QLabel类详解
文章目录 一、QLabel类介绍二、Properties(属性)三、Public Functions(公共函数)1.构造函数2.alignment与setAlignment函数 -- 标签内容的对齐方式3.buddy与setBuddy函数 -- QLabel关联的伙伴控件4.hasScaledContents与setScaledC…...
深入剖析 Android 开源库 EventBus 的源码详解
文章目录 前言一、EventBus 简介EventBus 三要素EventBus 线程模型 二、EventBus 使用1.添加依赖2.EventBus 基本使用2.1 定义事件类2.2 注册 EventBus2.3 EventBus 发起通知 三、EventBus 源码详解1.Subscribe 注解2.注册事件订阅方法2.1 EventBus 实例2.2 EventBus 注册2.2.1…...
End-to-End Object Detection with Transformers【目标检测-方法详细解读】
摘要 我们提出了一种新的方法,将目标检测视为一个直接的集合预测问题。我们的方法简化了检测流程,有效地消除了许多手工设计的组件,如非极大值抑制程序或锚生成,这些组件显式编码了我们关于任务的先验知识。新框架的主要成分,称为DEtection TRansformer或DETR,是一个基于…...
CSS3实现提示工具的渐入渐出效果及CSS3动画简介
上一篇文章用CSS3实现了一个提示工具,本文介绍如何利用CSS3实现提示工具以渐入的方式呈现,以渐出的方式消失。 CSS3主要可以通过两个样式来实现动画效果:animation和transition。 其中,animation需要自己定义一组关键帧从而实现…...
JVM 垃圾回收算法
一、如何确定为垃圾 引用计数法 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一,当引用为0,则认为对象可被回收。引用计数不能解决循环引用的问题 根可…...
吴恩达大模型系列课程《Prompt Compression and Query Optimization》中文学习打开方式
Prompt Compression and Query Optimization GPT-4o详细中文注释的Colab观看视频1 浏览器下载插件2 打开官方视频 GPT-4o详细中文注释的Colab 中文注释链接:https://github.com/Czi24/Awesome-MLLM-LLM-Colab/tree/master/Courses/Prompt-Compression-and-Query-Op…...
2.javaWeb_请求和响应的处理(Request,Response)
2.请求和响应的处理 文章目录 2.请求和响应的处理一、动态资源和静态资源javax.servlet(包) 二、Servlet体系1.简介2.HttpServlet3.Servlet生命周期 三、Request对象1.ServletRequest1)ServletRequest主要功能有:2)ServletRequest类的常用方法: 2.HttpServletReques…...
用C++、Python、Rust编写的有安全问题的B树
程序猿们都知道,B树(B-tree)是一种平衡的多路查找树,主要用于存储和检索大量数据,常用于数据库和文件系统中。 B树的特性包括: 每个节点可以包含多个关键字(键值)和对应的孩子指针…...
问题:当直齿圆柱齿轮的齿数少于?时,可采用 变位的办法来避免根切。 #学习方法#其他
问题:当直齿圆柱齿轮的齿数少于?时,可采用 变位的办法来避免根切。 参考答案如图所示...
nuScenes数据集深度解析:从传感器融合到3D目标检测的完整数据流
nuScenes数据集工程化实战:多传感器时空对齐与3D检测数据流优化 在自动驾驶研发领域,数据是算法迭代的基石。当我们谈论nuScenes数据集时,多数讨论停留在基础功能介绍层面,却鲜有从工程实现角度剖析其数据流设计的精妙之处。本文将…...
Python自动化运维实战:用Paramiko库5分钟搞定SSH批量管理(附完整代码)
Python自动化运维实战:用Paramiko库5分钟搞定SSH批量管理(附完整代码) 运维工程师的日常工作中,服务器管理往往占据大量时间。想象一下,当你需要同时更新50台服务器的安全补丁,或者批量收集100台设备的日志…...
Loop:Mac窗口管理的优雅革命,开源免费的全新体验
Loop:Mac窗口管理的优雅革命,开源免费的全新体验 【免费下载链接】Loop MacOS窗口管理 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 你是否曾在多窗口工作中迷失方向?Loop作为一款开源的macOS窗口管理工具,通过…...
GPT-OSS-20B参数调优实战:如何设置才能获得最佳生成效果
GPT-OSS-20B参数调优实战:如何设置才能获得最佳生成效果 1. 模型特性与调优基础 1.1 GPT-OSS-20B核心架构 GPT-OSS-20B作为OpenAI开源的重量级模型,采用混合专家架构(MoE)设计,总参数量210亿,其中活跃参数36亿。这种设计使其在…...
如何通过BaiduNetdiskPlugin实现下载性能提升:面向macOS用户的实用指南
如何通过BaiduNetdiskPlugin实现下载性能提升:面向macOS用户的实用指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 百度网盘作为常用的…...
Granite TimeSeries FlowState R1实战:基于卷积神经网络(CNN)的时序特征提取进阶
Granite TimeSeries FlowState R1实战:基于卷积神经网络(CNN)的时序特征提取进阶 你是不是也遇到过这样的问题?面对一长串传感器读数、股票价格波动或者服务器监控数据,感觉信息量巨大,却不知道从哪里入手…...
如何让2015年前的MacBook Pro焕发新生?OpenCore Legacy Patcher完全指南
如何让2015年前的MacBook Pro焕发新生?OpenCore Legacy Patcher完全指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否还在为手中的老款Mac无法升级到…...
5大场景重构AI协作流程:Awesome Claude Skills实战指南
5大场景重构AI协作流程:Awesome Claude Skills实战指南 【免费下载链接】awesome-claude-skills A curated list of awesome Claude Skills, resources, and tools for customizing Claude AI workflows 项目地址: https://gitcode.com/GitHub_Trending/aw/awesom…...
网盘直链解析技术指南:突破下载限制的高效解决方案
网盘直链解析技术指南:突破下载限制的高效解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改(改自6.1.4版本) ,自用,去推广…...
电脑系统由硬件系统和软件系统组成(来源网络,原创)
电脑系统由硬件系统和软件系统组成(来源网络,原创)电脑系统由硬件系统和软件系统组成。软件指操作硬件的各种语言或程序,硬件是指电脑系统中我们看得见、摸得着的物理设备。电脑硬件系统由运算器、控制器、存储器、输入设备和输出…...
