Flutter【00】热修复 / 动态化

1,928 阅读6分钟

前言

Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。

得到已经在多个业务成功接入Flutter,在保证用户体验的同时,显著提升了开发效率,节约了研发成本。

词汇表

热修复:让应用能够在无需重新安装的情况实现更新,帮助应用快速建立动态修复能力。

背景

由于客户端每次更新的时候,都需要经过发布平台的审核,不管是需要紧急修复的bug,还是想要快速上线的需求,都绕不过审核这个问题。而很多开发者都会遇到一个问题,就是审核时间过长。审核过长可能会导致bug不能及时修复,严重者造成巨大的经济损失。也可能导致新的业务无法及时上线,错失业务的最佳推广时机。所以,长久以来,客户端都存在一个热门的话题,那就是热更新。

热更新的需求由来已久,相应的各种解决方案也非常之多。其中有些已经开源,有些还在公司内部使用,还有些已经被平台封禁。目前业务接入Flutter最大的阻碍就是热修复能力的支持。

方案选型

腾讯 MXFlutter

简介:MXFlutter 是一套使用 TypeScript/JavaScript 来开发 Flutter 应用的框架。

设计思路:

把 Flutter 的渲染逻辑中的三棵树(即:WidgetTree、Element、RenderObject )中的第一棵(即:WidgetTree),放到 JavaScript 中生成。用 JavaScript 完整实现了 Flutter 控件层封装,实现了轻量的响应式 UI 框架,支撑JS WidgetTree 的 build 逻辑,build 过程生成的UI描述, 通过Flutter 层的 UI 引擎转换成真正的 Flutter 控件显示出来。

架构原理:

img

参考资料:github.com/Tencent/mxf…

58Fair

简介:Fair是为Flutter设计的动态化框架,通过Fair Compiler工具对原生Dart源文件的自动转化,使项目获得动态更新Widget的能力。

设计思路:

  • flutter源码经过编译,生成JSON,JS代码文件,这些文件会被打包成一个zip文件,从而减少传输过程中的消耗。在编写flutter代码的时候,需要对一些代码进行标记,这样在编译的过程中就会根据不同的标记情况,将我们编写的flutter代码分别编译成JSON和JS。
  • 打包好的zip包传输到服务器上,根据不同的版本一一进行管理,并且可以随时控制用户当前所需要展示的版本,当有线上问题的时候,可以随时由服务控制切换到指定的版本。
  • 客户端通过对版本的校验,获取到服务器想要展示的版本,然后下载对应的zip包,在客户端对文件进行一系列校验,以及本地的版本切换操作。
  • 本地Fair读取最新的文件,通过FairWidget对文件的解析,从而达到热更新的目的。

架构原理:

img

参考资料:github.com/wuba/fair

阿里 Kraken

简介:Kraken 是一款基于 W3C 标准的高性能渲染引擎。Kraken 底层基于 Flutter 进行渲染,通过其自绘渲染的特性,保证多端一致性。上层基于 W3C 标准实现,拥有非常庞大的前端开发者生态。

设计思路:

Kraken 基于 Flutter Rendering 层的实现进行了深度定制,在保留兼容 RenderObject API 的情况下,扩展出了兼容 W3C 标准的布局能力,并在此基础之上添加了 DOM,CSS 的解析处理,并对接 JavaScript 引擎,实现了一个类浏览器的技术架构。

架构原理:

img

参考资料:github.com/openkraken/…

腾讯Tinker

简介:Tinker 是 Android 的热修复解决方案库,它支持 dex、库和资源更新,无需重新安装 apk。

设计思路:

全量替换新的Dex。即我们完全使用了新的Dex,那样既不出现Art地址错乱的问题,在Dalvik也无须插桩。当然考虑到补丁包的体积,我们不能直接将新的Dex放在里面。但我们可以将新旧两个Dex的差异放到补丁包中,最简单我们可以采用BsDiff算法。

在Android里面,Flutter打包之后的产物是一个.so文件(libapp.so),Tinker热更新支持so文件更新,自然也就支持Flutter热更新,差量替换Flutter so库。

架构原理:

img

参考资料:github.com/Tencent/tin…

字节 Mars

简介:火山引擎应用开发套件MARS,是字节跳动技术驱动,经字节跳动上百款 APP 研发实践验证、诸多企业使用的面向多端开发场景的应用研发工具。

Chimera Flutter Code Push

简介:Chimera 定制化修改了Dart编译器,生成可解释执行字节码,来实现Code Push(热更新)。

设计思路:

将Dart层代码分为两层,一层JIT执行,另一层AOT执行。当然Flutter默认执行的方式是AOT执行,如果我们想要热更新并且又不会丢失很大的性能,那么 JIT + AOT 混合执行会是我们最好的方案之一。

参考资料:github.com/ChimeraFlut…

方案对比

热修复方案腾讯 MXFlutter58Fair阿里 Kraken腾讯Tinker字节 MarsChimera Flutter Code Push
学习成本:
适配情况:Flutter1.0Flutter2.0+无版本限制Flutter2.0+无版本限制
痛点:版本适配较慢,功能支持不全。 前端的开发方式。只能修复Widget,不能修复逻辑。 支持热修复的Widget数量较少。 增加工作量,需要编写模版文件前端的开发方式。仅支持Android。付费。 没有大公司背书。
包大小增加Android:27.1M (包含7.8M Flutter引擎)Android:27.1M (包含7.8M Flutter引擎)Android:11.3M (包含7.8M Flutter引擎)无(引入Tinker的APK大小没有增加,热更新后包大小影响未知)Android:4.8M Flutter引擎相比官方引擎从7.8M降到4.8M
社区活跃度star:570star:1200star:4500star:16400--
学习成本高,JS按照Dart的方式写布局高,较多的模版文件编写客户端高,前端低

方案倾向:

腾讯Tinker。

原因:

  • 无需引入新的开发框架,无学习成本。
  • 无需付费,开源项目,社区活跃。
  • 腾讯背书。
  • 无需修改已有的Flutter代码。
  • 无Flutter版本限制。

总结

由于Google没有计划支持Flutter热更新,各种Flutter热更新技术方案都是社区推动。

本次调研了社区所有的Flutter热更新方案,每种方案都有自己的优缺点,根据业务情况选择合适的技术。

参考文档

混栈开发之Android端Flutter热更新,兼容FlutterBoost

Flutter Android 端热修复(热更新)实践

带你不到80行代码搞定Flutter热更新

Tinker Flutter热修复

混栈开发之Android端Flutter热更新-Tinker篇