干货|Flutter 原理与闲鱼深度实践

王康(正物)—— Flutter 官方成员 阿里巴巴技术专家,之前主要负责 Flutter 在闲鱼中的混合开发体系,目前重点关注 Flutter 深入度以及生态相关的工作。本文将分享三方面内容, Flutter 的原理、 Flutter 在闲鱼中的应用,最后介绍我们在深度方面的一些探索。

01、Flutter 原理

当我们谈到跨平台框架时,可能会想到很多备选方案。包括早期的 HTML 和 Cordova , 后来的 React Native , Weex ,以及这两年很是流行的 Flutter ,它们都在不同阶段不同程度上解决了我们对跨平台的诉求。如果我们从一些关键指标包括动态性、性能来观察,他们的区别还比较明显。

HTML 和 Cordova 具有最好的动态性,但他们的性能却是最差的,RN / Weex 具有良好的动态性。Flutter 则是一个纯原生的设计,其设计使它天生具有很好的性能与跨端一致性。

Flutter 是如何实现优秀的性能和跨端一致性的呢?从设计上可以看出 Flutter 在操作系统之上包含了三个层次。最下面是平台相关的嵌入层,其向上提供一个 Surface 用以绘制,建立了相关的线程模型和事件循环机制。在此之上则是一个平台无关的引擎,包括用于绘制的 Skia ;Dart 的运行时,开发模式下包括一个解释器;还有一部分是文本绘制相关内容。最上面就是用 Dart 语言编写的 Flutter 框架,也是我们最常接触到的内容。Flutter 框架包含一个完整分层的 UI 框架,从基础的 Foundation 库,到动画手势,再到渲染,之上又提供了各种丰富的 Widget 库。为了方便开发者使用, Flutter 还提供了两套不同风格的组件库,针对安卓的 Material Design 的组件库和针对 iOS 的 Cupertino 风格的组件库。

从这个设计可以看出,Flutter 和平台相关的内容,其实只提供 Surface 和线程/事件循环模型的嵌入层部分。这种类似用游戏引擎的方式来开发应用的设计很好解释了为什么它具有优秀的跨端一致性。

我们常常说 Flutter 具有这样的几个特点:

  • 精美

丰富的 Widget 库、 Material Design 和 Cupertino 风格的系统库、组合式的 API 、像素级的控制力可以使开发者便捷地构建精美的应用。

  • 高效开发&执行快速

Dart 语言是为数不多同时支持 JIT 和 AOT 编译的语言。开发期使用 JIT 编译,支持了广受欢迎的热重载功能,开发者可以像 PS 图片一样来开发应用,开发效率高。发布后 Flutter 使用 AOT 编译, Dart 代码最终被编译成 ARM 汇编指令,运行快速。

  • 开放

Flutter 是开源项目,其整个的开发,工作流都是完全遵循开源项目的运作来完成的。

02、Flutter 在闲鱼中的应用

说完 Flutter 原理,我们来看 Flutter 在闲鱼中的应用。在我们的研发中有几个核心关注的问题。

  • 开发效率

闲鱼技术是一个相对较小的团队,但业务需求比较重,开发人员少需求多,这种情况下效率就非常重要。还有部分原因是 iOS 安卓两端开发资源不均衡的问题,

  • 用户体验

我们的设计要求我们具有很好的跨端一致性,其设计也是同一套风格。

  • 执行性能

不管是复杂的交互还是动画,都要求其具有不错的性能。

Flutter 的设计很好地满足了闲鱼业务研发关注的这些问题,这也是我们采用它的原因。

我们怎么样让 Flutter 从无到有地在闲鱼中落地与上线?这里面包括前期的调研,研发期的混合开发体系,以及如何保质保量在线上运行。

2017 年,我们去接触和调研 Flutter ,其当时还处在 Alpha 阶段。

我们需要去了解它的原理,看它是如何具有所宣称的诸多优势;对其性能做测试,看能否满足要求;包大小的增加怎么样,这个量是否可承受;音视频调的出发点在于业务场景,我们的详情和发布页面包括了很多图片和视频;工具链上 Flutter的开发体验如何;我们甚至做了一个 MVP Demo ,这个产品中我们实现了包括发布,详情、我的页面等主要设计与逻辑;此外我们还很关注其社区的成熟度,确保在遇到问题时,可以通过自己对原理的理解或者社区去解决问题。

要使用 Flutter 我们就会面临一个混合研发体系的问题。其最开始的设计是面向纯 Flutter 开发的应用。而我们的应用是在原生项目中嵌入 Flutter ,也就是 Add2App 。事实上在国内,即便是一个纯 Flutter 的应用,很多时候,因为二方、三方库的原因,也会成为一个混合工程。通过我们的实践与影响, Add2App 也变成了 Flutter 演进的重要方向。

工程层面上,我们的团队中存在两个视角。一个是传统的 Native 开发的视角,一个是 Flutter 视角。我们并没有直接使用 Github 上的 Flutter 项目,主要是因为可控性的问题。因为国内的安卓碎片化以及 ROM 中 opengl 的实现不规范,使我们不得不存在一些针对性的处理逻辑,也就是引擎定制。其产物通过定制的 Flutter 最终被 fwn 工程所使用。fwn 工程包含了实际 Flutter 业务,其 Flutter 代码通过产物集成的方式,通过 pod( iOS ) ,和 gradle ( Android ),最终集成到原生项目中。

混合开发不仅包括工程体系,也包括页面侧的逻辑。我们一开始就涉及到了混合页面体系,以 Android 为例简要介绍下原理。每个 Flutter 页面对应了一个原生的 BoostFlutterActivity , BoostFlutterActivity 通过各自的 BoostFlutterView 去绑定单例的 FlutterEngine 。当 Flutter 页面在做切换时 BoostFlutterActivity 也会同步切换,将 FlutterEngine 动态地 Detach 和 Attach 。Native 和 Flutter 之间可以互相关闭和打开页面, Native 的生命周期也会同步到 Flutter 侧。

Flutter 支持 UI 构建以及逻辑实现,但可能我们还需要去获取 wifi 状态或电量等系统状态。

面对这样的场景, Flutter 提供了很多机制去扩展应用。以获取电量为例, Flutter 提供了 Channel 机制用于同 Native 之间的双向通信。Dart 代码在 Release 下会变成汇编代码,直接调用到 Engine ( C++ ),再调用到 OC (直接)或 JAVA (通过 JNI 间接),这种设计下的性能是原生体验。

Flutter 不仅在逻辑侧提供了 Channel 机制去扩展应用,在渲染相关也提供了一些机制去做更多。我们写的 Flutter 视图布局最终会通过 DartRuntime 调用到 Engine 中的 LayerTree->Paint 方法。在这个渲染管线中, LayerTree 会调用到 SkCanva->Draw ,最终通过 PresentRenderBuffer / SwapBuffer 将内容绘制到 GPU 上。LayerTree 中,包含很多种 Layer ,其中有一个特殊的 TextureLayer 可用于扩展。

以 Android 为例, TextureLayer 可以在 SurfaceTexture 的帮助下,同一个 Surface 相关联。基于 Surface 可以将视频播放的内容传入并完成渲染,或者结合 VirtualDisplay 和 Presentation ,完成 NativeView 的嵌入。需要注意的是,因为 VirtualDisplay API 的限制,此部分的逻辑需要 API Level 在 20 及其以上。

也就是说 Flutter 提供了 Channel 机制用来扩展系统特性相关的逻辑,通过 Texture 机制来支持视频播放器等场景和原生视图的嵌入。

在开发过程中我们其实也遇到很多问题,不管是混合栈,或者是视频嵌入, iOS 兼容等,很多今天已经不再是问题, 但我还是想和大家分享下其中的一些思路。首先了解各层面原理是很重要的, Flutter 本身是一整套庞大完整的内容,针对不同层次团队中都应该有相关的同学有一定理解;要有能力识别出关键问题;可以复现和定位问题,提供最小化的 Demo 用于复现它,在通过社区解决问题的场景下,最小的可复现的 Demo 是尤其重要的;还有就是要同社区有紧密的联系与合作。

我们不仅要关注技术本身,也一定要保证业务稳定。这里有一些手段来和大家分享。用灰度来发现那些容易发现的问题,用分桶和降级策略逐渐增加 Flutter 的业务比例,通过线上 APM 去监控质量,这些手段来保障质量。

总的来看,目前我们有 20 多个页面来使用 Flutter 构建, Crash 水平在万分之一的数量级,详情页等帧率在 52 帧以上,可交互的页面加载时长是 300 毫秒。

这些是我们目前使用 Flutter 开发的部分页面,包括详情发布、我的等。涉及到的设计元素较多,包括视频、图片、聊天、评论、拍摄等比较完备的内容。我们最早使用详情和发布来验证 Flutter ,也是要看 Flutter 能否支撑业务场景最复杂的情况,此外也需要分桶与降级的机制来保障最坏情况下的业务可用性。背后的演进并不容易,也是个逐渐改善解决的过程,但这并不是原理上的大问题,很多是细节上的问题,典型如安卓上面的碎片化问题。

除了业务落地外,我们也做了一些体系化的建设,这里面很多内容都同 Native 侧。就 Flutter 而言,从下往上,包括一些针对 Flutter 的 SDK ,像其特有的 APM 采集;大量 SDK 的桥接;在其上,构建用于 Flutter 开发的编程框架,如 Fish Redux , FlutterBoost 等,最终去支撑各个 Flutter 业务的研发。

03、Flutter 深度实践

分享完 Flutter 在闲鱼中的应用,接下来介绍我们的一些深度实践。

在 Engine 侧,主要解决 Android 碎片化所带来的问题以及 iOS 上的内存优化。

在 Dart 侧的工作主要围绕着 Dill 展开,我们开发了一个基于 Dill 编织的 AOP 框架,提供了一种新的方式来实现中间语言层面的代码编织。基于此,我们也正在做 JSON 转换,轻量级反射等部分的内容。

在 Flutter 侧,我们的工作包括 APM , FlutterBoost , FishRedux 等面向业务研发的开发框架。

在 UI 部分,我们也在做一些图片转代码部分的工作。

简单介绍下 AOP 框架和 UI To Code 两部分的工作。

如果想去解决 AOP For Flutter 的问题,有哪些问题需要解决呢?首先我们要描述清楚这段代码,是想对哪个库、哪个类的哪个方法去做怎么样的操作;要让 AOP 代码没有侵入性,使原生代码和 AOP 代码可以分开编写,并最终在合适层面进行编织;我们还需要一种机制,去提取散落各处的注解形式的切面逻辑,并将其应用到目标方法中去。

在 AspectD 的设计中,通过提供面向 Dart 的 Aspect 设计,我们解决了描述切面的问题;通过提供基于 Kernel to Kernel Transform的Transformer ,我们解决了提取注解和编织的问题。

相对于传统 AOP 框架所提供的 Call 和 Execute 的语法, AspectD 还提供了 Inject 的语法,这主要是因为 Flutter 禁止反射造成的。

目前还有一个问题就是对于构建过程的侵入性。Flutter 的构建过程( flutter tools )和我们以前的习惯有区别,并没有提供太多的扩展点。目前 AspectD 本身有一点对于构建流程的修改,用于拦截原始的 Dill 构建,并用操作过的 Dill 文件替换原始 Dill 文件,这一侵入性同 AOP 本身没有什么关系,我们正在和 Flutter 团队去解决这一问题。

还有就是我们在做的 UI To Code 。即通过 UI 去分析版面,识别组件属性和布局,生成中间的 DSL 描述。后端基于此,完成针对 Flutter 的布局推导,树的构建优化与最终代码转化。

04、总结 & 展望

回顾一下,本文我们分享了跨平台方案与 Flutter 的原理。在 Flutter 的业务落地中如何去调研问题,如何完成混合开发体系和能力扩展,如何去解决关键问题和保证线上质量;也展开介绍了我们在 AOP 和 UI To Code 等领域做得一些深入性工作。

展望未来,我们谈谈 Flutter 的一些未来的趋势。

首先 Flutter 原理很自然地支持了 Mobile 和 Desktop ,以及神秘的 Fuchsia 系统。针对 Flutter For Web ,我最近也写了一点分析,这是一个实验性的项目,从原理上来说可以支持 Flutter 代码无成本地运行在 Web 上,但可能存在性能的损失。当然如果业务不是很复杂,或不是很高的性能要求的话,可以考虑尝试下。

除了我们自身的实践外,我们也希望一些大的应用,可以更多地进来。更复杂的应用场景和生态链的支持可以让 Flutter 的社群更加完善。

目前我们现在也在做一些 Flutter China 的工作,核心目标就是完善国内的生态降低大家的开发门槛,让更多的团队能够受益。最后,大家如果有什么问题可以在下方评论区进行交流。

 

精彩回顾

 

原文链接
本文为云栖区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算,巨头们的背水一战

作者 | 马超责编 | 伍杏玲头图 | CSDN 下载自视觉中国出品 | CSDN(ID:CSDNnews)最近国内各IT巨头技术布局都颇有看点,先是腾讯宣布将投入5000亿,用于新基建的进一步布局(将重点投入云计算、人工智能、区块链…

基于函数计算的 Serverless AI 推理

前言概述 本文介绍了使用函数计算部署深度学习 AI 推理的最佳实践, 其中包括使用 FUN 工具一键部署安装第三方依赖、一键部署、本地调试以及压测评估, 全方位展现函数计算的开发敏捷特性、自动弹性伸缩能力、免运维和完善的监控设施。 1.1 DEMO 概述 通过上传一个…

《Flutter in action》开放下载!闲鱼Flutter企业级实践精选

复制链接到浏览器 https://yq.aliyun.com/download/3792?utm_contentg_1000081730 下载。 闲鱼是国内最早使用Flutter的团队,也是Flutter业务线渗入最深的团队之一。 现在承载亿级流量的闲鱼将多年最佳实践经验整理成册,《Flutter in action》 正式面世…

阿里HBase高可用8年抗战回忆录

前言 2011年毕玄和竹庄两位大神将HBase引入阿里技术体系,2014年接力棒转到东8区第一位HBase commiter天梧手中,多年来与淘宝、旺旺、菜鸟、支付宝、高德、大文娱、阿里妈妈等几乎全BU合作伙伴携手共进,支撑了双十一大屏、支付宝账单、支付宝…

nginx 1.9.9 Linux 环境安装

文章目录一、软件下载和安装Nginx相关依赖1. 安装Nginx相关依赖2. 下载Nginx二、源码安装Nginx2.1. 解压2.2. nginx默认配置2.3. 编译安装2.3. 查找安装路径2.4.启动nginx2.5. 查看是否启动成功一、软件下载和安装Nginx相关依赖 1. 安装Nginx相关依赖 yum -y install gcc zli…

Java面向对象部分小结

Java面向对象部分小结 第一天: 1. 了解面向对象和面向过程 2. 对象是什么,静态特性(属性),动态特征(方法) 3. 类和对象的关系 类是抽象的,对象是具体的类是具有相同属性和行为(…

音视频应用驶入快车道 开发者如何快速追赶这波技术红利?

受访人 | 融云CPO 任杰 作者 | June 图片来源 | 视觉中国 毋庸置疑,随着5G时代的到来,实时音视频技术将会上升到一个全新的高度。 5G时代发生巨变的远远不止网速,凭借5G网络的高带宽,低延迟和大并发性,音视频应用场…

Mysql 8.0 安装教程 Linux Centos7

文章目录一、软件下载上传1. 下载2. 上传二、软件安装配置2.1. 解压mysql2.2. 创建data文件夹 存储文件2.3. 创建用户组以及用户和密码2.4. 授权用户2.5. 切换到bin目录下2.6. 编辑my.cnf文件2.7. 添加mysqld服务到系统2.8. 授权以及添加服务2.9. 启动mysql2.10. 查看启动状态2…

重磅发布 | 全球首个云原生应用标准定义与架构模型 OAM 正式开源

Kubernetes 项目作为容器编排领域的事实标准, 成功推动了诸如阿里云 Kubernetes (ACK)等云原生服务的迅速增长。但同时我们也关注到,Kubernetes 的核心 API 资源比如 Service、Deployment 等,实际上只是应用中的不同组…

今天的作业 --- 去重

使用Set的写法: public String myMethod1(String str){ //Set方法Set setnew HashSet();for (int i 0; i < str.length(); i) {set.add(str.charAt(i));}String s "";for (Object o :set) {so;}return s;}由于Set集合内不会存储重复的字符,所以…

2020 AI 产业图谱启动,勾勒中国 AI 技术与行业生态

《2020年国务院政府工作报告》提出&#xff0c;重点支持「两新一重」建设。其中「两新一重」中的第一个「新」&#xff0c;就是新基建&#xff0c;而人工智能是新基建的重要组成部分。新基建首次被纳入政府工作报告后&#xff0c;各大科技厂商纷纷押注&#xff0c;重金投向「新…

从零开始入门 K8s | Kubernetes 网络概念及策略控制

一、Kubernetes 基本网络模型 本文来介绍一下 Kubernetes 对网络模型的一些想法。大家知道 Kubernetes 对于网络具体实现方案&#xff0c;没有什么限制&#xff0c;也没有给出特别好的参考案例。Kubernetes 对一个容器网络是否合格做出了限制&#xff0c;也就是 Kubernetes 的…

SwitchHosts

SwitchHosts 是一个管理、切换多个 hosts 方案的工具。 它是一个免费开源软件。 下载地址 https://github.com/oldj/SwitchHosts/releases

开放计算架构:蚂蚁金服是如何用一套架构容纳所有计算的?

蚂蚁金服在过去十五年重塑支付改变生活&#xff0c;为全球超过十二亿人提供服务&#xff0c;这些背后离不开技术的支撑。在 2019 杭州云栖大会上&#xff0c;蚂蚁金服将十五年来的技术沉淀&#xff0c;以及面向未来的金融技术创新和参会者分享。我们将其中的优秀演讲整理成文并…

一个神秘URL酿大祸,差点让我背锅!

作者 | 编程技术宇宙责编 | Carol封图 | CSDN 付费下载自视觉中国神秘URL我叫小风&#xff0c;是Windows帝国一个普通的上班族。上一回说到因为一个跨域请求&#xff0c;我差点丢了饭碗&#xff0c;好在有惊无险&#xff0c;我的职场历险记还在继续。“叮叮叮叮~~~~”&#xff…

支付宝王益:40岁写30年代码是一种什么体验?

对于蚂蚁金服研究员王益而言&#xff0c;2019年是个颇有纪念意义的年份。今年他整40岁。从10岁开始&#xff0c;写代码整30年。这30年来&#xff0c;他当过“不务正业”的学生&#xff0c;创纪录地在大一就考下系统分析员&#xff0c;“单枪匹⻢”闯荡过从国内到硅谷的多家知名…

牛!2020年,这项技术将获得1,000,000,000元人民币注资!

在今年的特殊情况下&#xff0c;国外的AI明星公司轰然倒塌&#xff0c;一夜之间倒闭。又有某AI大厂一年亏了60亿……就像看破楼市一样&#xff0c;我们不由心想&#xff1a;“AI&#xff0c;会不会从头到尾就是一场泡沫&#xff1f;”但是&#xff0c;最近国家发的“定心丸”来…

基于阿里云的 Node.js 稳定性实践

前言 如果你看过 2018 Node.js 的用户报告&#xff0c;你会发现 Node.js 的使用有了进一步的增长&#xff0c;同时也出现了一些新的趋势。 Node.js 的开发者更多的开始使用容器并积极的拥抱 ServerlessNode.js 越来越多的开始服务于企业开发半数以上的 Node.js 应用都使用远端…

Knative 实战:基于阿里云 Kafka 实现消息推送

在 Knative 中已经提供了对 Kafka 事件源的支持&#xff0c;那么如何在阿里云上基于 Kafka 实现消息推送&#xff0c;本文给大家解锁这一新的姿势。 背景 消息队列 for Apache Kafka 是阿里云提供的分布式、高吞吐、可扩展的消息队列服务。消息队列 for Apache Kafka 广泛用于…

“编程能力差,90%输在了数学上!”CTO:多数程序员都是瞎努力!

01从未得到过重视的问题一流程序员学数学&#xff0c;二流程序员学算法&#xff0c;低端看高端就是黑魔法。可能有人以为这就是个段子&#xff0c;但有过工作经验的都知道&#xff0c;这其实就是程序员的真实写照&#xff01;想一想&#xff0c;我们学习、求职、工作的场景中&a…