之所以发这篇文章,主要是关于multiple-flutter[1]无论是Flutter多引擎的介绍还是实践,参考的资源太少to,including官方issues没有很多有价值的信息。这几个月,真的是在坑的泥潭里挣扎。不过还好,走出了一条窄路,可供大家参考。关于Flutter多引擎的优缺点,笔者这里不多做介绍,只说最重要的一点:如果有同页面Native+Flutter混合布局的需求(UI一致性/成本降低和效率提升),但是整个App不能或者用Flutter替换整个页面,可以考虑使用FlutterEngineGroup(multiple-flutters)。闲话不说,先看看效果吧。APP展示如上图红框所示,是4种不同引擎的FlutterView,绘制在同一个Native布局中。篇幅有限,就不贴视频了。有兴趣的同学可以下载“设计稿”看看效果(不过现在还在AB卷阶段,可能看不到新版的模板页面~)。多引擎使用为什么市场上使用多引擎的人这么少?Multiple-flutters绝对是Flutter中的王者。首先,Flutter版本至少要升级到2.10+,才能拥有iOS/Android多引擎同步布局的初步可用性。但是,建议升级到Flutter3+。iOS2.5.3到2.10.5版本存在内存崩溃风险。具体可以参考同事这篇帖子解决Flutter导致iOS内存崩溃的问题。第一次渡劫:首先,在连接FlutterEngineGroup时,发现编译没有问题,但是FlutterView无法正常显示。查了很多资料(没有有用的资料),和官方的FlutterDemo对比了一下。花了2个小时。天哪,最后只能锁定Flutter版本或者flutter_boost的问题。死马当成活马医,直接把Flutter升级到最新版本(2.10.2)及相关依赖升级,发现Debug正常。。。然后在打包flutterAndroid时,发现flutter_boost报错。从githubissues了解到flutter_boost不支持Flutter2.10.x,出现了闪白屏的问题。根据issues的建议,2.8+版本存在Release包不可用的问题,建议降到2.5.3。这是FlutterEngineGroup初期落地的可行性坑终于爬出来了。因为2.5.3同时布局了多个FlutterEngine(3-10个不等),所以会出现ANR。查找解决方案无果时,尝试升级到当时最新版本的Flutter2.10.5,结果正常。升级过程中又遇到了一个问题。作者公司项目中还有很多flutter_boost的实现,flutter_boost由于某些原因不支持Flutter2.5.3及以上版本(参见他们的issues)。然后需要修改Fork下的flutter_boost才能正常使用。FlutterEngineGroup离实用太远,缺乏内部固定的布局方式。只能通过外部布局位置的大小来让FlutterView自适应。通信层极其繁琐。从有限的Demo可以看出,三个终端都需要实现BridgeChannel。桥接方式使用“string”作为对应类型,导致个性化开发和维护成本非常高。应用场景狭窄,多个FlutterEngine只能通过Native交互进行通信。在FlutterDebug模式下,多个引擎=内存爆裂。需要使用FlutterRelease来稳定和归一化到官方描述的180K/Engine内存使用效果。我们是如何使用脚本开发出一套FGUIComponentAPI工具链来链接Native和FlutterUI的关系的。确保Flutter开发是非直观的。对于Flutter,UI是照常开发的,独立调试可以直接验证效果。保证Native开发没有任何意义。对于Native来说,只是直接引用和使用源类,不需要关心它的实现。它开箱即用。额外的好处是天然的UI单元测试,只需要在Flutter端进行验证。特别是内置了官方推荐的Pigeon插件来处理modeltransfer的问题,但是Pigeon插件的执行效率不高,而且执行的组件越多执行越慢,所以函数文件比较和跳过的功能稍后添加。加速。后续会考虑更换鸽子,不使用dart,效率问题可以改用python来解决。在开发过程中,作者使用YAML定义UI组件,通过FGUIComponentAPI多方向生成各种代码和服务。上图是自动生成的开发文档。可以看到Native调用是完全不敏感的。右边的预览页面也是很自然的利用了Flutter的跨端Web能力,文档上直接输出了FlutterExample。到底有多少个坑?作者还在一步步踩着呢。比如市面上常见的pub要谨慎使用,尤其是与Native交互的插件,基本不考虑多引擎实现。比如常用的flutter_cache_manager,由于使用了sqlite数据库进行存储,在多引擎同时布局的情况下,Android设备可能会出现数据库等待导致图片缓存写入失败的问题/read(当然你可以定义cachedKey来指定使用不同的db来解析)。其实这不是第三方库的问题,而是多引擎市场上真正用的人太少了。没有需求,就没有市场。可以看到作者几乎把整个字母表都踩了一遍……手动狗头。[1]multiple-flutters:https://flutter.cn/docs/development/add-to-app/multiple-flutters
