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热更新技术探索的更多相关文章
- iOS热更新技术被苹果官方警告?涉及到RN、Weex、JSPatch!!!
		今天一早,不少iOS开发群都炸窝了,原因是部分iOS开发者收到了苹果的警告邮件: 有开发者质疑可能是项目中使用了JSPatch.weex以及ReactNative等热更新技术.对于修复bug提交审核的 ... 
- iOS热更新技术被苹果官方警告?涉及到RN、Weex、JSPatch
		本文为转载文章 故事背景: 这两天,不少iOS开发群都炸窝了,原因是部分iOS开发者收到了苹果的警告邮件: 有开发者质疑可能是项目中使用了JSPatch.weex以及ReactNative等热更新技术 ... 
- Unity热更新技术整理
		一.热更新学习介绍 1.什么是热更新 举例来说: 游戏上线后,玩家下载第一个版本(70M左右或者更大),在运营的过程中,如果需要更换UI显示,或者修改游戏的逻辑,这个时候,如果不使用热更新,就需要重新 ... 
- RN学习1——前奏,app插件化和热更新的探索
		react_native_banner-min.png React Native(以下简称RN)有大量前端开发者的追捧.前端开发是一个活跃的社区,一直尝试着一统前后端,做一个全栈开发,RN就是他们在客 ... 
- Android热更新技术——Tinker、nuwa、AndFix、Dexposed
		一.热修复技术作用 线上app BUG紧急修复,不重新发版,不重新安装,在线远程修复问题 二.局限性与适用场景 补丁只能针对单一客户端版本,随着版本差异变大补丁体积也会增大: 补丁不能支持所有的修改, ... 
- Android为TV端助力之QQ空间热更新技术
		直接上代码 package com.enjoy.patch; import android.content.Context;import android.os.Build;import android ... 
- [Cocos2d-x]Lua 资源热更新
		什么是热更新 所谓的热更新,指的是客户端的更新. 大致的流程是,客户端在启动后访问更新的URL接口,根据更新接口的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端. 热更 ... 
- APP热更新方案
		为什么要做热更新 当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App.测试.向各个应用市场和渠道换包.提示用户升级.用户下载.覆盖安装. 重 ... 
- unity游戏热更新
		链接:https://pan.baidu.com/s/1ggWP0OF 第 1 章 : 热更新技术学习介绍 课时1:101-热更新技术学习介绍 11:55 什么是热更新? 举例来说 游戏上线后,玩家下 ... 
- 移动端热更新方案(iOS+Android)
		PPT资源包含iOS+Android 各种方案分析:https://github.com/qiyer/Share/blob/master/%E7%83%AD%E6%9B%B4%E6%96%B0%E5% ... 
随机推荐
- 记一次 .NET某汽车零件采集系统 卡死分析
			一:背景 1. 讲故事 前段时间有位朋友在微信上找到我,说他的程序会出现一些偶发卡死的情况,让我帮忙看下是怎么回事,刚好朋友也抓到了dump,就让朋友把 dump 丢给我,接下来用 windbg 探究 ... 
- Maven学习笔记1:Maven基本介绍和安装配置
			一.认识Maven 官网 http://maven.apache.org/ 上面有最权威的说明,其中包括下载.安装.运行示例,但是是英文版的. Maven是什么 Maven是一个项目管理工具. 它有何 ... 
- [数据分析与可视化] Python绘制数据地图1-GeoPandas入门指北
			本文主要介绍GeoPandas的基本使用方法,以绘制简单的地图.GeoPandas是一个Python开源项目,旨在提供丰富而简单的地理空间数据处理接口.GeoPandas扩展了Pandas的数据类型, ... 
- Linux基础知识归纳
			1.Linux:Linux is not Unix.主要用于企业的服务器端.Windows不开源(系统价格大概2000左右,安装软件也特别贵,例如Offers就6000左右等).基于内核的操作系统(r ... 
- java魔功心法-范型篇
			前言: https://www.cnblogs.com/LoveBB/p/17277662.html 什么是范型 JDK 1.5开始引入Java泛型(generics)这个特性,该特性提供了编译时类型 ... 
- 四月二十三号java基础知识
			1.异常是指在程序运行中由代码产生的一种错误2.按照错误的性质将错误分为语法错.语义错.和逻辑错三种3.语法错是有由于违反程序设计语言的语言规则而产生的错误,如标识符未标明.表达式中运算符与操作数类型 ... 
- Git提交代码仓库的两种方式
			目录 一: 两种本地与远程仓库同步 1 git 远程仓库 提交本地版本库操作 提交到远程版本库操作 1.Git 全局设置: 2.增加一个远程仓库地址 3.查询当前存在的远程仓库 5.本地版本库内容提交 ... 
- Auto-GPT测评:自信、努力、不合格
			这两天,Auto-GPT 爆火 https://github.com/Torantulino/Auto-GPT 它是一款让最强语言模型GPT-4能够自主完成任务的模型,让整个AI圈疯了.它的嘴大突破是 ... 
- DRF的认证组件(源码分析)
			DRF认证组件(源码分析) 1. 数据库建立用户表 在drf中也给我们提供了 认证组件 ,帮助我们快速实现认证相关的功能,例如: # models.py from django.db import m ... 
- 零样本文本分类应用:基于UTC的医疗意图多分类,打通数据标注-模型训练-模型调优-预测部署全流程。
			零样本文本分类应用:基于UTC的医疗意图多分类,打通数据标注-模型训练-模型调优-预测部署全流程. 1.通用文本分类技术UTC介绍 本项目提供基于通用文本分类 UTC(Universal Text C ... 
