Flutter混合开发原理及闲鱼深度实践
王康(正午) - 阿里巴巴技术专家,Flutter官方成员,之前负责闲鱼Flutter的混合开发体系,目前专注于Flutter的深度和生态方面。上班。本文将从三个方面进行分享,Flutter的原理、Flutter在闲鱼的应用,最后我们会深入介绍一些我们的探索。
01。 Flutter 原理

当我们谈论跨平台框架时,可能会想到很多选项。包括早期的HTML和Cordova,后来的React Native、Weex和Flutter这两年非常流行,它们都以不同的方式解决了我们不同阶段的跨平台需求。如果我们看一些关键指标,包括动态和性能,它们的差异是相当明显的。
HTML和Cordova动态最好但性能最差,RN/Weex动态较好。 Flutter 是纯原生设计,本身就具有良好的性能和设计的一致性。
Flutter 是如何做到性能优异、整体统一的?从设计上可以看出,Flutter在操作系统之上包含了三层。最底层是与平台相关的嵌入层,提供了绘制的表面,并形成了相关的线程模型和事件循环机制。除此之外,还有一个独立于平台的引擎,包括用于绘图的Skia; Dart 运行时,包括开发模式下的解释器;以及一些与绘图文字相关的内容。最上面是用Dart语言编写的Flutter框架,这也是我们处理最多的。 Flutter框架包含了完整的分层UI框架,从Foundation核心库到渲染的动画手势,此外还提供了各种丰富的Widget库。为了方便开发者使用,Flutter 还提供了两种不同类型的组件库,即适用于 Android 的 Material Design 组件库和适用于 iOS 的 Cupertino 风格组件库。
从这个设计中可以看出,Flutter 以及与平台相关的内容实际上只提供了 Surface 和线程/事件循环模型的嵌入层。这种设计,类似于使用游戏引擎来开发应用程序,解释了为什么它具有出色的交叉端。
我们常说Flutter有以下几个特点:
- 优秀
丰富的Widget库,Material Design和Cupertino风格的系统库,结合API和像素级控制可以让开发者轻松构建漂亮的应用程序。
- 高效开发、快速执行
Dart语言是少数同时支持JIT和AOT编译的语言之一。开发期间采用了JIT编译,支持时下流行的热重载功能。开发者可以开发PS图像等应用,开发效率高。发布后,Flutter采用AOT编译,Dart代码最终编译成ARM汇编指令,运行速度快。
- Open
Flutter是一个开源项目,其整个开发和工作流程完全按照开源项目的运作进行。
02。 Flutter在闲鱼中的应用

讲完了Flutter的原理,我们来看看Flutter在闲鱼中的应用。我们的研发工作有几个关键问题。
- 开发效率
闲鱼科技团队规模比较小,但业务需求比较重,开发人员少,需求多。在这种情况下,效率就非常重要。部分原因是iOS和Android开发资源不平衡。
- 用户体验
我们的设计要求我们两端之间有很好的统一性,它的设计也是风格一致的。
- 性能
无论是复杂的交互还是动画,都需要良好的性能。
Flutter 的设计与闲鱼的业务研发关注点非常契合,所以我们采用了它。
我们如何从头开始在闲鱼上运行 Flutter?这包括前期研究、研发期间的混合开发体系以及在线保质保量。
2017年,我们接触并研究了当时还处于alpha阶段的Flutter。
我们需要了解它的原理并了解它如何具有许多声称的好处。测试其性能,看看是否满足您的要求;增加包装尺寸怎么样?这个数量是否可以承受?音视频调整的出发点是业务场景。我们的信息和出版物页面有大量的图片和视频; Flutter在工具链方面的开发经验是怎样的?我们甚至还做了 MVP 演示。在这个产品中,我们实现了发布、详细信息和我的页面。以及其他主要设计和逻辑;另外,我们特别关注它的社区的成熟度,这样当我们遇到问题的时候,我们可以通过自己对原理或者社区的理解来解决。
在使用Flutter时,我们面临着混合研发体系的问题。其最初设计仅适用于在 Flutter 中开发的应用程序。我们的应用程序将Flutter嵌入到原始项目中,即Add2App。事实上,在中国,即使是一个纯粹的 Flutter 应用程序也常常因为第二个和第三方库而变成一个混合项目。得益于我们的实践和影响,Add2App也成为Flutter发展的一个重要方向。
在工程层面,我们团队有两个观点。一种是传统的原生开发视角,一种是Flutter视角。我们没有直接使用Github上的Flutter项目,主要是因为可控性问题。由于国内Android的碎片化以及ROM中opengl的实现不规范,我们需要有针对性的处理逻辑,即引擎定制。其产品最终通过定制Flutter应用于fwn项目中。 fwn项目包含实际的Flutter业务,其Flutter代码最终通过pod(iOS)和gradle(Android)通过产品集成集成到原始项目中。
混合开发不仅包括设计系统,还包括侧面逻辑。首先我们讨论了混合页面系统,并以Android为例简单介绍了其原理。每个Flutter页面对应一个原生的BoostFlutterActivity,BoostFlutterActivity通过对应的BoostFlutterView绑定一个单独的FlutterEngine。当 Flutter 页面发生变化时,BoostFlutterActivity 也会同步变化,FlutterEngine 会动态分离和附加。 Native和Flutter可以互相关闭和打开页面,Native的生命周期也同步到Flutter端。
Flutter 支持用户界面构建和逻辑,但我们可能还需要获取系统状态,例如 wifi 状态或电池电量。
面对这样的场景,Flutter提供了很多机制来扩展应用。作为获取力量的一个例子,Flutter 提供了与 Native 双向通信的通道机制。Dart代码成为发布代码,直接调用到Engine(C++),然后调用到OC(直接)或JAVA(通过JNI间接)。根据此模型的性能是一种原生体验。
Flutter 不仅提供了用于扩展应用程序的逻辑通道机制,还提供了一些允许您在渲染时做更多事情的机制。我们编写的Flutter视图布局最终会调用到Engine的LayerTree DartRuntime-
作为Android示例,我们可以提到TextureLayer可以使用SurfaceTexture附加到同一个Surface。基于Surface,可以传递和渲染视频播放内容,也可以结合VirtualDisplay和Presentation来完成一个NativeView的嵌入。需要注意的是,由于VirtualDisplay API的限制,本节中的逻辑需要API级别20或更高。
也就是说,Flutter 提供了通道机制来扩展系统属性相关的逻辑,并使用Texture 机制来支持视频播放器、原生视图等嵌入场景。
其实我们在开发过程中遇到了很多问题,无论是混合栈、视频嵌入、iOS兼容性等等,很多今天已经不再是问题了,但我还是想跟大家分享一些想法。首先,了解每个级别背后的原理很重要。 Flutter本身就是一套庞大而完整的内容。对于不同层次的群体,有关学生必须有一定的了解。他们必须能够识别关键问题;他们必须能够重现并查明问题。做一个简单的介绍以重复它。在通过社区解决问题的场景下,最小的可玩演示尤其重要;还需要与社区的密切联系和合作。
我们不仅要关注技术本身,还要保证业务的稳定性。这里有一些方法与大家分享。使用灰度发现容易发现的问题,使用集群和降级策略逐步增加Flutter的业务份额,并通过在线APM跟踪质量。这些方法保证了质量。
我们目前有超过 20 个使用 Flutter 构建的页面。碰撞率约为万分之一。信息页及其他页面的图像速度大于52张。交互页面的加载时间为300毫秒。
这些是我们目前在Flutter上开发的一些页面,包括详情贴、我的等等。它包含了很多设计元素,包括视频、图片、聊天、评论、照片等内容比较全面的内容。我们首先通过细节和版本来验证Flutter,看看Flutter是否可以支持最复杂的业务场景。此外,还需要分组和降级机制来保证最坏情况下的业务可用性。其背后的发展并不容易,也是一个逐步完善和解决的过程。不过这从原理上来说并不是什么大问题,而是涉及细节的很多问题,比如Android的碎片问题。
除了业务实现之外,我们还做了系统化的建设,很多都是和Native侧相同的。至于Flutter,它从下到上包括了一些Flutter的SDK,比如它独特的APM集合;合并大量的SDK;在此之上构建Fish Redux、FlutterBoost等Flutter开发的编程框架,最后支持Flutter各类业务的研发。
03、Flutter深度实践

闲鱼分享完Flutter应用后,会介绍一些我们的深度实践。
在引擎方面,主要解决iOS中Android碎片和内存优化带来的问题。
Tika 的工作主要围绕 Dill 展开。我们开发了一个基于Dill weaving的AOP框架,它提供了一种新的方式来实现中间语言级别的代码编织。在此基础上我们还做了JSON转换、光反射等部分。
在Flutter方面,我们的工作包括APM、FlutterBoost、FishRedux等业务研发的开发框架。
在用户界面部分,我们还做了一些将图像转换为代码的工作。
简单介绍一下AOP框架和UI To Code的操作。
如果你想解决AOP For Flutter问题,你需要解决哪些问题?首先,我们需要清楚地描述这段代码要对哪个库、哪个类的哪个方法执行什么样的操作;我们需要让AOP代码非侵入性,这样原生代码和AOP代码可以分开编写,最后有一个合适的Weave层;我们还需要一种机制来以分散在各处的注释的形式提取方面逻辑并将其应用到目标方法。
在设计AspectD时,我们通过为Dart提供Aspect设计来解决描述方面的问题;通过提供基于 Kernel to Kernel Transform 的 Transformer,我们解决了注释提取和编织问题。
与传统AOP框架提供的Call和Execute语法相比,AspectD还提供了Inject语法。这主要是因为Flutter防止了反射。
目前的另一个问题是施工过程的破坏性。 Flutter的构建过程(flutter工具)与我们之前的方法不同,并没有提供很多扩展点。目前,AspectD 本身对构建过程进行了一些更改,用于停止原始 Dill 版本并用使用的 Dill 文件替换原始 Dill 文件。这种入侵与AOP本身无关。我们正在与 Flutter 团队合作解决此问题。问题。
我们还正在开发 UI To Code。换句话说,用户界面用于分析布局、识别组件属性和布局以及创建中间 DSL 描述。后端以此为基础进行Flutter布局推导、树结构优化以及最终的代码转换。
04。总结与展望

回顾过去,这篇文章我们分享了跨平台解决方案和Flutter的原理。如何排查Flutter的业务实施问题,如何完成混合开发体系和扩容,如何解决关键问题并保证上线质量;它还展示了我们在 AOP 和 UI To Code 等领域所做的深入工作。
展望未来,我们来谈谈Flutter未来的一些趋势。
首先,Flutter原理天然支持Mobile和Desktop以及神秘的Fuchsia系统。我最近写了一篇关于 Flutter For Web 的分析。这是一个实验项目,理论上可以支持免费在网络上运行 Flutter 代码,但性能可能会受到影响。当然,如果业务不是很复杂或者对性能要求不高的话,可以尝试一下。
除了我们自己的实践之外,我们也希望能有一些更大的应用。更复杂的应用场景和生态链支持可以让Flutter的社区更加完整。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。