手把手带你自研一套Flutter动态热更新框架

吉太
• 阅读 211

学习地址1:https://pan.baidu.com/s/1qCc1jcfOU-wRn5Wp3YF9Tw 提取码:ager 学习地址2:https://pan.baidu.com/s/1sz8esUBzpU5a3jhDK6Hy5w 提取码:ccrq

手把手带你自研一套Flutter动态热更新框架————跨平台高手必修课--Flutter动态化解决方案实战 1、什么是动态化? 目前移动端应用的版本更新, 最常见的方式是定期发版,无论是安卓还是iOS,都需要提交新的安装包到应用市场进行审核。审核通过后,用户在应用市场进行App的下载更新。

而动态化, 就是不依赖更新程序安装包, 就能动态实时更新页面的技术。

2、动态化的必要性 为什么需要动态化技术呢? 因为上述定期发版更新应用的方式存在一些问题,比如:

审核周期长, 且可能审核不通过。 周期长导致发版本不够灵活, 紧急的业务需求不能及时上线。 线上出现急需修复的bug时,需要较长修复周期,影响用户体验。 安装包过大, 动辄几十兆几百兆的应用升级可能会让用户比较抗拒。 即使上线了,也无法达到全部用户升级, 服务端存在兼容多版本App的问题。 面对这些问题,如果能实现app增量、无感知更新,实现功能同步。无论是对公司还是用户都是非常重要的需求,能实现app动态化更新就显得非常重要,能很好的解决以上问题:

随时实现功能升级,不存在应用市场长时间审核和拒绝上线问题,达到业务需求快速上线的目的。 线上bug可以实时修复,提高用户体验。 可以减小发版功能包体积,只需要替换新增功能即可。 功能保持一致,类似网页一样,发版后用户同步更新,不存在旧版本兼容问题。 接下来,我们就来分析一下,目前业内主要的Flutter动态化更新方式。

代码实战: 1、第一屏渲染特别慢,且与代码量的增加成正比。整个过程包含: 字节码解码(我们下发的产物是Lua字节码)、LuaVM执行字节码指令。借助性能分析工具,分析发现pcall函数执行时间很长,展开后每个函数执行时间却很短,但嵌套层次非常深。

一开始并没有怀疑是类似递归的函数调用,通过调试lua-vm执行字节码指令的整个过程,发现同一个Package会被require多次。我们在用typescript写代码的时候,一般情况一个class对应一个ts文件,同时每个class会依赖同一个Widget。例如Text Widget基本上每个页面都会使用。而typescript编译成Lua代码后,每个module就是一个Lua package。

Lua要使用一个package首先需要require。导致对于同一个Text Widget会被调用多次,并且互相有依赖的话还会产生死循环错误, 可以理解为循环引用。这个用一个online lua playground就可以测试,所以同样用dart实现的VM也会遇到这个问题,以下是伪代码:

TypeScript: import { Widget } from "runtime/flutter/widget"; import { StatelessWidget } from "runtime/flutter/widgets/statelessWidget"; import { Text } from "runtime/flutter/widgets/text"; export class DemoPage extends StatelessWidget { public build(context: BuildContext): Widget { return Text("演示demo") } } require Lua函数的实现: //修复前 local package = {preload={}, loaded={}} local function require(file) return package.preloadfile end

//修复后 local package = {preload={}, loaded={}} local function require(file) local loadedModule = package.loaded[file] if loadedModule == nil then package.loaded[file] = true loadedModule = package.preloadfile package.loaded[file] = loadedModule return loadedModule end return loadedModule end

如下面代码的例子,一个 if 语句的 JSON 节点下发后,经过 parser 之后会得到一个 IfStatement 对象,这类对象都有一个特点就是包含几个属性,和一个运行时入口方法 evaluate(Scope scope)。这个方法在抽象类 Evaluative 类中,所有语句和表达式的类都会继承于此,自动获得 evaluate 方法,其中属性部分是在解析过程中解析成 Dart 对象后通过构造方法的参数传入的。 class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); }

class _MyAppState extends State { List widgets = [];

Future fetchData() async { // Send HTTP request to remote server and get JSON data final response = await http.get(Uri.parse('https://example.com/data.json'));

// Parse JSON data into Flutter Widget tree
final jsonTree = json.decode(response.body);
final widgetTree = createWidget(jsonTree);

setState(() {
  widgets = widgetTree;
});

}

@override void initState() { super.initState(); fetchData(); }

@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: SingleChildScrollView( child: Column( children: widgets, ), ), ), ); } }

Widget createWidget(Map<String, dynamic> json) { final type = json['type']; final childrenJson = json['children'] as List; final children = [];

for (final childJson in childrenJson) { children.add(createWidget(childJson)); }

if (type == 'Text') { return Text(json['text']); } else if (type == 'Column') { return Column(children: children); } else if (type == 'Row') { return Row(children: children); } else { throw Exception('Unknown widget type: $type'); } }

点赞
收藏
评论区
推荐文章
赵颜 赵颜
5个月前
[16章]SpringBoot2 仿B站高性能前端+后端项目(2023新版)
资料地址1:https://pan.baidu.com/s/1cxQDKIi7iu1mGmjRr9a0Mw提取码:tz5s资料地址2:https://pan.baidu.com/s/1DjmuC6Id4oUCNVbxfgcMg提取码:qtf3今天给大家讲讲
赵颜 赵颜
5个月前
[15章]深入学习小程序框架底层原理,培养双线程思维
学习地址1:https://pan.baidu.com/s/1ridzu0mrj1vrfT07fdReuw提取码:3zd2学习地址2:https://pan.baidu.com/s/1SChnJCGf03sybLfyAnkCA提取码:c862前端高手特训从
赵嬷嬷 赵嬷嬷
4个月前
[16章]慕课甄选-2024年Flutter零基础极速入门到进阶实战
学习地址1:https://pan.baidu.com/s/1iOH2xMvdMyBAJla5PeHuUg提取码:hjhi学习地址2:https://pan.baidu.com/s/1Iwj10AL7jdum19WQz1jdA提取码:0n8xFlutter
赵嬷嬷 赵嬷嬷
3个月前
[31周]AI人工智能算法工程师体系课2024
学习地址1:https://pan.baidu.com/s/1wpfuPvDb4Y4BQEKPt7bc1A提取码:q7xz学习地址2:https://pan.baidu.com/s/1CYzDHRmYKDPb29MfKN0qlg提取码:2jt4今天给大家讲
双寿 双寿
2个月前
跨平台高手必修课--Flutter动态化解决方案实战(14章)
学习地址1:https://pan.baidu.com/s/1qCc1jcfOUwRn5Wp3YF9Tw提取码:ager学习地址2:https://pan.baidu.com/s/1Er2jt50Ewiiz6a5CrUMlIQ提取码:walv手把手带你自研
鲍二家的 鲍二家的
2个月前
Stable Diffusion 商业变现与绘画大模型多场景实战(附课件+软件包)
学习地址1:https://pan.baidu.com/s/1vWnJbAfDu1khiMvhaoEbQ提取码:q5pb学习地址2:https://pan.baidu.com/s/17peKwZEuCyMQobR2X8ifg提取码:zypi一、什么是Sta
鲍二家的 鲍二家的
2个月前
AI Agent智能应用从0到1定制开发(12章)
学习地址1:https://pan.baidu.com/s/1ccnoXsPCUg4eP5rSrD0UA提取码:o0mu学习地址2:https://pan.baidu.com/s/1JYJ6dMkwgx0XWQnCM6Q0A提取码:2m68AIAgent已
双寿 双寿
2个月前
[12章]AI Agent智能应用从0到1定制开发
学习地址1:https://pan.baidu.com/s/15IbktHy54IdZRg3g7PWWKQ提取码:v7lt学习地址2:https://pan.baidu.com/s/1JYJ6dMkwgx0XWQnCM6Q0A提取码:2m68AIAgent
鲍二家的 鲍二家的
1个月前
[7章]Go从入门到进阶,大厂案例全流程实践
学习地址1:https://pan.baidu.com/s/1kZq7Rc7PHBRYEzWL85FCA提取码:0udi学习地址2:https://pan.baidu.com/s/1Rr5G2U3YSbwhFTLMHH2keA提取码:j0viGo语言高效、
鲍二家的 鲍二家的
1个月前
前端跳槽突围课:React18底层源码深入剖析
学习地址1:https://pan.baidu.com/s/1DnzdWB9oCEMGOx9jvYjAjg提取码:hqw0学习地址2:https://pan.baidu.com/s/1kUlrpqlboZIrRmXpiT9TLw提取码:ur5i在当下就业环