真当Flutter不能热更新?众能动态化Flutter

效果展现

上面铁军中的这个关于咱们页面以及转换为了动态化页面。java

动态化标签 python

动态化路由 一个flutter页面转换为动态化页面,只须要添加动态化标签和动态化路由就好了,对业务页面的开发修改不多,相比其余动态化方案是巨大的优点json

方案对比

方案名称 美团 满帮 众能
简述 dart文件编译为json,使用自定义运行时调用proxy方法 使用js经过自定义js虚拟机调用flutter业务组件 dart文件编译为lua字节码,使用lua虚拟机调用proxy方法
开发语言 dart js dart
语法支持 不支持async和await 支持async和await
flutter控件支持 所有支持 只能使用自定义组件 所有支持
开发调试 使用dart自带debugger 自定义debugger 使用dart自带debugger
核心原理 使用自定义运行时解析json,调用proxy 经过自定义js虚拟机调用proxy 使用修改后的lua虚拟机调用proxy方法

三个方案都必须使用proxy方法,由于flutter中的dart阉割了反射,必须经过某种方式经过proxy方法来调用dart方法。 proxy方法以下图,这是扫描铁军App自动生成的: 众能的方案对比美团,优点在于使用了成熟的lua虚拟机的机制,在运行时执行的是指令,例如加法 会被编译两个loadConstant指令和一个binaryArith指令。而美团的方案核心是自定义的运行时,基本单位是语句和表达式,粒度粗了一个级别,直接的影响就是不支持async和await等异步语法。xcode

众能的方案对比满帮,优点在于自动支持全部的flutter组件、第三方和自定义组件,同时开发调试时是使用flutter自带的编译器和调试器。而满帮方案开发时只能使用js语言,同时只能使用有限的flutter组件,有限的业务组件。缓存

核心原理比喻

众能的方案核心其实和乐高积木同样: 普通flutter页面就像上面这个塑料恐龙,要改动一点必须在工厂从新生产。 使用众能动态化的页面,至关于使用不少个小块的乐高积木模仿出了原始的页面,小块的乐高积木就是proxy方法。 因此动态化页面实际上是高仿的页面,和原始的页面有些细微的不一致。 可是优点就是动态化的页面能够在本身在运行时修改。markdown

动态化流程1-jenkins打包

jenkins流水线在xcode编译前加入了动态化工具下载,以及动态化编译就是流程图中黄色的部分。异步

动态化流程2-启动注册路由

每个动态化dart文件都会编译出.out字节码文件,但只有带routerModel的页面.out文件都才要在启动时执行生成routerModelasync

.out字节码文件就是上图这样,在启动时执行这个字节码就会生成routerModel,而后动态化虚拟机就休眠了,直到进入动态化页面才会启动。工具

这个字节码的内容是和lua字节码彻底一致的,甚至在项目初期真正的lua字节码能够在mars_vm中运行并输出同样的结果,python、java等虚拟机中字节码也是相似结构,都有指令集,本地变量集合等信息。 虚拟机是另一种语言来执行目标语言的,例如lua官方虚拟机是使用c语言来执行lua,也有go语言版本的。python虚拟机有java、c、go等多个版本。 众能的这个虚拟机是dart实现的,能够执行lua和dart。lua

动态化流程3-进入页面

进入页面后就会执行路由routerModel的block,完成页面初始化为为statefullWidget,并按照StatefullWidget自己的生命周期调用对应方法。

最简单的虚拟机指令展现

动态化运行hello_world代码,完成hello world字符串打印,这个在虚拟机里面是比较复杂的,由于要用到包加载等功能。 最简单的指令是算数运算指令,例以下面这个加法。

a = b + 100
复制代码

会被编译为三条指令,load指令从寄存器中加载b到栈顶,load指令从常量表中加载c到栈顶, 执行算数指令把栈顶的两个数弹出进行算数运算,结果放入a寄存器的位置。

待完善的功能点

一、目前虚拟机调试时不能和原始的dart代码对应上,还好预留了行号信息等字段,一个月内应该能够加上。

二、目前的命名空间实现不够完善,同一个库内类名不能重复。 三、调用proxy方法的指令过多,经过修改命名空间的机制,应该能够把指令数减半。 四、没有实现方法缓存,反复调用同一个方法的话,会重复使用指令加载这个方法。

相关文章
相关标签/搜索