![聊聊FlutterEngage大会中的特性落地](https://static001.infoq.cn/resource/image/55/8e/557329cc8919efb4053cf931818c7a8e.jpg)
flutter engage 大会已经过去一段时间,闲鱼团队作为国内较早大规模使用 flutter 的团队,对 flutter 的每一次升级都感到兴奋无比,网上已经有很多介绍大会的 flutte 2 特性的介绍文章,就不会赘述具体特性,今天会从开发者的角度如何看待以及评论这些新特性,评估这些特性在业务场景应用,最后对 flutter 未来的展望,将来还有哪些值得期待的功能。
Flutter2 新特性
全面支持 Windows、MacOS、Linux、Web、iOS、Android 六大平台
本次 flutter engage 大会最大的亮点莫过于支持更多平台,在原有移动端的基础上,新增桌面、web 端,从此 flutter 往真正的多平台迈向了更加坚实的一步,flutter2 看起来更像全新的引擎。
![](https://static001.geekbang.org/infoq/f3/f3289199b6864f63a62e75733b8298b6.png)
桌面平台
flutter2 全面支持目前主流的 Windows、MacOS、Linux 桌面平台,其实对于 fluttre 架构而言,因底层使用 skia 本身就跨多平台的缘故,从移动端扩展到桌面端是非常顺畅。
优点
开发者编写一份 Dart 渲染代码,便可以部署到多个平台,是一个非常流畅的开发方式。
目前存在的问题
除了编写 Dart 渲染代码外,还需要关注工程所依赖的库是否都完美的支持了桌面版平台。谷歌声称其官方维护所有 pub 库已经全部支持 web/macos/windows 等平台,除此外社区其他的库还需要等待作者们升级,要想流畅升级的开发者们可能还需要尚待时日。
想要迁移至桌面平台的开发者们可以自行评估自己的工程所依赖的库。如果依赖的库大部分来自谷歌官方,且都支持了桌面平台,较少平台相关库,升级过程应该是非常顺畅的。
闲鱼观点
相比于业内其他成熟的跨平台桌面开发框架,学习成本比 Qt 偏小(Dart 语言),性能比 electron 好,但现成的组件没有 electron 成熟,非常适合工具类的应用从移动端平滑的迁移到桌面端。
Flutter web
flutter web 最开始的设计思路时使用 Dart 代码操作 css 或者 Dom 接口进行渲染,而到 flutter2 后已升级为 framework 和渲染层完全隔离,使用同一份 Dart 代码可以编译成多个平台。下面两图是基于操作系统的 flutter 架构和基于浏览器的 flutter 架构。
![](https://static001.geekbang.org/infoq/f6/f67ff2578c94573953d01c2da6187007.jpeg)
Windows/MacOS/Linux/iOS/Android 架构
![](https://static001.geekbang.org/infoq/d0/d06a5dcbcb6c4278d1836c44d17f2799.jpeg)
web 架构
Flutter web 推荐场景
相同一份 Dart 代码如今能跑在各种平台下了,部署到服务器上也能跑在 web 端了,那么在上面常见下使用 flutter web 是最合适的呢?
谷歌推荐使用 flutter web 的场景有
Progressive Web Apps(PWA)
Single Page Apps(SPA)
现有 app 迁移
PWA 和 SPA 是相对于传统 web 应用而言,传统 web 网页遵循请求-应答协议,网页内容的刷新和加载伴随着多次的网络请求。而 PWA 和 SPA 相对则会请求少,或者请求时回包的数据。比如 PWA,可以简单理解为这是一种期望运行在各种设备,接近 Native 应用保持一致体验的使用 web 应用。简单而言这是在用 web 技术模拟原生应用,这个应用渲染大部分代码无需网络请求,即开即用,可以无网络时离线运行,和普通原生功能一致,只是这是使用 web 技术编写,运行在浏览器的应用。常见的例子是安装在 android 设备的 web twitter 应用。
而 SPA 和 PWA 界限在于,SPA 的界面代码第一次需要网络请求,而后每次的请求都是纯数据的请求。
![](https://static001.geekbang.org/infoq/f6/f6eea08aa6840e3c64d92da416494a44.png)
PWA 应用原理
![](https://static001.geekbang.org/infoq/c0/c06a7b74b840ad597c178a8eaf204e06.png)
SPA 应用原理
这三种场景使用 flutter web 的初衷是充分利用它相比传统 web 网页优越的渲染性能。如果使用 flutter web 来编写非常经典的 web 应用则既失去了利用 flutter web 优越渲染性能,又没法和传统 web 一样充分利用其成熟的生态。
如何迁移 Flutter web?
无需配置特别的设置,直接使用 IDE(VSCode 或者 Android Studio)编写 flutter 工程后,使用flutter build web
即可体验。
但有以下几点需要重点关注:
依赖的 Flutter plugin 需支持 web 对于跨平台的 plugin,需要重新支持 web
响应式布局 相对于原有移动设备屏幕小,web 端可能会运行在各种屏幕下,各种交互方式需要进行优化。
页面跳转/导航 页面的跳转从移动设备的单窗口,变成浏览器下的多窗口,多 tab
桌面设备交互风格(鼠标、键盘) 支持浏览器下更加常用的鼠标键盘等的交互方式
渲染模式(HTML/CanvasKit) 需要根据业务需求选择 flutter web 的渲染方式(HTML 渲染方式安装包小,性能较差,CanvasKit 渲染方式安装包大,性能好)
目前存在的问题
因为浏览器的特性存在决定了,如要对一些于操作系统强相关的 plugin 库进行 web 的特性支持时,会存在困难,比如文件系统,各种社交媒体登录分享 sdk 等。因此进一步缩小了其使用的场景。
闲鱼观点:
flutter web 的渲染性能虽不如基于操作系统架构的原生 flutter 应用,但优于能部署在服务器,但又比一般的 web 渲染性能稍好,所以非常适合对性能在有要求的 web 活动业务场景中使用。或作为原生 flutter 界面崩溃时的一种业务降级兜底方案,在紧急场景业务充当救火队员的角色。
支持多屏设备
这是微软为将自家设备 surface duo 设备,开辟一个独立的分支给 flutter 支持多屏特性。
![](https://static001.geekbang.org/infoq/81/81bf0a3ab37ad7a43ed65a05dafe2b9b.png)
支持的特性能很好的支持多屏设备的特点,比如:
Extended Canvas: 双屏共享一个大 canvas
List-Detail: 左列表,右详情
Two Page:多页,看书应用
Dual View:双屏,相同内容不同角度的双屏
Companion Pane:左显示,右配置
代码样例:
比如 TwoPanel 是新增的 Widget,panel1、panel2 传入两个不同屏幕的 widget
![](https://static001.geekbang.org/infoq/f0/f01c02e259ca8e26308e2a60930550c5.png)
但目前这个分支由微软维护,暂未合入到 flutter 的主分支中 flutter github 中开辟的两个 issue 在专门跟进 (issue77156[1] ,issue24756[2]) ,感兴趣的可以去到下方链接了解概况 https://devblogs.microsoft.com/surface-duo/flutter-dual-screen-foldable/ [3]
Dart 语言新特性
flutter2 中除了新增平台等新特性外,配套的 Dart 语言也推出新特性
Sound null safety
Sound null safety 我们暂且称为空安全声明,目的是通过显式声明可能为 null 的变量,增加 Dart 语言的鲁棒性。因为 Dart 语言变量可以存 null 或者具体的值,因此在日常的开发中可能因为忘记赋值或者变量延迟赋值,导致访问某个变量时为 null,导致程序运行时抛出 exception。这个功能推出后,可以从源码级解决 null 异常导致的错误。简单的操作是在类型声明后添加?以标识这个变量是可以为 null 的。
![](https://static001.geekbang.org/infoq/fa/fac4ecc83a8ced6953732479a75a4e87.png)
如何迁移?为 Dart 了这个语法糖,对于已有的项目如何升级?谷歌对此也提供了配套的升级工具,只需要在工程目录下使用 dart migrate,就可以帮助你扫描整个工程中潜在的待替换的变量
![](https://static001.geekbang.org/infoq/6c/6c66013f6739606071816504dd509583.png)
优点
缓解因变量为 null 而抛出 exception 而引发的白屏,用户无法操作等体验问题。
目前存在的问题
但是开发者对于现存工程,一旦 Dart 代码一下子全部改造,无疑会增加系统风险,而且对于测试范围也会是非常繁重的任务。
闲鱼观点:
这个特性很好的将风险提前暴露在了编码阶段,又能顺带解决神出鬼没的 null 问题,性价比很高。但大规模改造也会引来问题,但这个特性非强制性的原因,为解决大规模改造可能导致的系统性风险,可以采取分批改造的方法进行。
FFI(Foreign Function Interface)
动态库函数调用特性。特性的目的是让开发者更加方便的调用操作系统的动态库。这个特性其实很早就已经有了,如今正式转正 stable,开发者们可以放心使用了。
使用的方式也非常直观
编译某个平台下的动态库
Dart 代码中加载动态库,将 Dart 的函数和动态库的函数绑定
Dart 调用已绑好的函数即可
![](https://static001.geekbang.org/infoq/68/684d272e9aee848ef7daa43495c17ffa.png)
FFI 更多详细看这里https://pub.dev/packages/ffigen
优点
由静态库迁移到动态库后,可以减少安装包大小
相比于注入 plugin 模式去调用操作系统的接口,FFI 更加友好,真正的按需加载,建议对于不常用频次少的的系统调用可使用 FFI,对于优化整个 engine 初始化的加载速度有很好益处。
闲鱼观点:相对于旧的 platform channel 这种与 C 交互而言,FFI 因需要动态库加载和符号绑定,性能不占优势,开发者们在选择这两种技术方案时是要权衡的。
社区其他
混合栈的跳转有官方支持了吗?
对于众多团队而言,最初都是由原生的应用引入 flutter,所以如何在原生界面和 flutter 界面跳转变成开发者非常强需求的功能点,flutter boost 的推出是为解决混合栈界面跳转而提出的解决方案,但该方案也并非完美,最大问题在于多个 flutter 界面跳转时需要多开 engine,无法共享 engine 中相同内存。针对这个问题 flutter2 中已经支持了 engine 多实例[4],但官方也说了,这是一个正式实验中有风险的功能,但官方未提供不同技术栈之间的跳转方案(iOS/Android->flutter,flutter->iOS/Android),但在官方对于这个问题的技术路线图中也说到,以后这个特性是需要需要继续开发的,但目前还是建议使用 futter boost 方案。
多 flutter 界面技术路线:https://docs.google.com/document/d/1fdKRufqUzQvERcqNIUSq-GdabXc4k8VIsClzRElJ6KY/edit#
细枝末节
除了以上的一些比较大的功能点外,还有一些提升效率小工具
flutter fix[5]:dart 代码分析工具,能高亮废弃代码等
dartPad2.0[6]: 浏览器运行 flutter 小工程,所见即所得,验证小问题神器
FFI Gen[7]FFI Dart 代码生成器,根据 C 接口批量生产 FFI 的 Dart 接口
展望
从作为开发者的角度而言,flutter2 扩展了更多的平台,让它在跨平台的路上越走越远。但与此同时,众多平台推出的同时,也会带来更多细枝末节的小问题,小 issues,同时从官方的下一步的动作看,接下来将会聚集在支持一个社区中响应度比较大的好几个问题中
为解决混合栈中内存过大而开发的多引擎实例特性
为解决开发时出现的性能 UI 调试难的问题,在着力开发 devtools 工具
dart 语言因缺少命名空间,正在开发的类似特性等等
这些问题我们也在持续跟进中,如有进一步的进展,我们也会和大家持续的探讨。更多 flutter 相关技术热点,欢迎大家持续关注闲鱼技术。
References
[1]
issue77156: https://github.com/flutter/flutter/pull/77156
[2]
issue24756: https://github.com/flutter/engine/pull/24756
[3]
https://devblogs.microsoft.com/surface-duo/flutter-dual-screen-foldable/ : https://devblogs.microsoft.com/surface-duo/flutter-dual-screen-foldable/
[4]
engine 多实例: https://flutter.dev/docs/development/add-to-app/multiple-flutters
[5]
flutter fix: https://flutter.dev/docs/development/tools/flutter-fix
[6]
dartPad2.0: https://dartpad.dev/flutter
[7]
FFI Gen: https://pub.dev/packages/ffigen
本文转载自:闲鱼技术(ID:XYtech_Alibaba)
评论