1. 引言前端
移动互联网发展十余年,伴随着 Android、iOS 等智能手机的不断普及,移动端已逐步取代 PC 端,成为兵家必争之地。正所谓“得移动端者得天下”,移动端已成为互联网领域最大的流量分发入口,一大批互联网公司正是在这大趋势下崛起。java
2. 为何须要跨平台技术git
伴随着移动互联网的高速发展,公司间竞争愈来愈激烈,如何将好想法快速落地、快速试错,成为备受关注的问题。提高研发效率、缩短研发周期,保障产品快速试错并能快速迭代新功能,让新产品新功能以最快的速度同时抵达 Android、iOS 等多端用户。github
众所周知,Android 应用采用 Java 或 Kotlin 编写,iOS 应用采用 Objective-C 或 Swift 编写,Web 端采用 HTML /CSS/JavaScript 编写。当须要开发支持多端的应用,每一端都须要独立研发、测试,一直到上线,以及后续的维护工做,工做量成倍增涨,势必延长研发周期。web
为了解决多端独立开发的问题,跨平台技术便应运而生,各大互联网公司为此都投入大量人力,因而出现了各类跨平台技术框架,面对移动领域的跨平台技术方案的层出不穷,又该如何作技术选型呢?面试
3. 移动端技术选型算法
做为移动端的跨端技术方案,所关注无外乎如下这4个方面:研发效率、动态性、多端一致性、性能体验。shell
4. 跨平台技术划分编程
对研发效率和体验的不断追逐,移动端的跨平台技术方框架层出不穷,然则天下武功众多,万变不离其宗,从其核心本质来划分,可大体分为如下三大类:小程序
5. 跨平台技术演进
跨平台技术,一直以来是每个有追求的开发者所追逐的梦想,同时也是守旧者的噩梦,跨平台的多端一体化方案势必颠覆现有的原生各端独立开发模式,接下来列举众多的跨平台技术中最为关键的几个技术方案的演进阶段。
从上图能够看出,技术演进过程大体分如下三个阶段: 第一阶段,采用WebView技术绘制界面的Hybrid混合开发技术,经过JS Bridge 将系统部分能力暴露给 JS 调用,其缺点是性能较差,功能受限,扩展性差,不适合交互复杂的场景,好比Cordova。 第二阶段,针对WebView界面性能等问题,因而绘制交还原生渲染,仅仅经过JS调用原生控件,相比WebView技术性能体验更好,这是目前绝大部分跨平台框架的设计思路,好比React Native、Weex。另外,最近小程序也比较火,第一和第二阶段的融合,依然采用WebView做为渲染容器,经过限制Web技术栈的子集,规范化组件使用,并逐步引入原生控件表明WebView渲染,以提高性能。 第三阶段,虽然经过桥接技术使用原生控件解决了功能受限问题,提高性能体验,但相比原生体验差距仍是比较大,以及处理平台差别性很是耗费人力。因而Flutter提出自带渲染引擎的解决方案,尽量减小不一样平台间的差别性, 同时媲美原生的高性能体验,所以业界对 Flutter有着极高的关注度。
面对现有的如此多跨平台方案,为什么当下最火的跨平台技术是Flutter,有哪些优点呢?
RN、Weex均使用JavaScript做为编程语言,JavaScript做为前端开发语言,在跨平台开发中可谓大放异彩,利用web技术不只能开发出网站,也能够开发手机端web应用和移动端应用程序,似有一统三界(Android、iOS、Web)的趋势,这就是你们常说的“大前端”时代。这些技术方案流畅度不太好,平台一致性较差,至今还没能大面积取代原生开发。
Flutter是以Dart语言编写,开发体验更接近客户端,从你们使用反馈来看也是如此,Flutter开发环境这一套的流程对于前端开发来讲并不太友好。Flutter的定位一样是多端一体化,可是以客户端为首,先磨平Android和iOS双端开发体验,再逐步向Web端渗透,从Flutter规划的Roadmap也能看出,Flutter for web目前仍处于预览版,Flutter客户端方向都已经如火如荼上线了很多应用。
在此以前,你们常说“大前端”,对于Flutter技术,在笔者看来称之为“大移动端”更贴切,Flutter的UI框架优先支持客户端(Android/iOS)应用的同时,而后再适配Web端。移动互联网时代,很多公司都制定“移动优先”的战略,甚至只开发移动端,没有Web端。移动互联网的时代造就“大移动端”,Flutter做为一款能作到媲美原生的高性能跨平台技术方案,或许一统天下。
在跨平台技术领域,只要挑战在,技术就不会停滞,伴随着技术不断演进与革新,终将走向美好。
6. Flutter技术优点
Flutter是完全的跨平台方案,既没有采用webView,也没有采用JS桥接原生控件,而是自行实现一套UI框架,在引擎底层经过Skia渲染到屏幕。对于UI以外所须要使用的移动设备自身提供的服务,好比相机、定位、屏幕触摸等,则采用Platform Channels跟原生系统通讯的方式来实现。
对于Flutter优点,回到前面讲到移动端技术选型的4要素,研发效率、动态性、多端一致性、性能体验,分别对应下面这一组词语。
图解:
固然,不得不说目前的Flutter确实不够尽善尽美,会存在一些不够尽善尽美之处,好比生态不够健全,包体积问题,但其该方案的上限比较高,想象空间比较大,相信更多开发者参与进来,通过更多打磨,将来会作得更好。
7. 业界发展近况
2017年5月Google I/O大会正式对外公布Flutter,到2018年12月发布Flutter1.0,引起全球大量的开发者和企业开始研究Flutter。StackOverflow 2019年的全球开发者文件调查中,Flutter被评选为最受开发者欢迎的框架之一,超过了TensorFlow和Node.js。
到目前,全球愈来愈多的公司已经在你们耳熟能详的知名APP中使用Flutter技术并落地,尤为国内知名互联网公司对Flutter投入度很大,社区也是很是活跃。
8. Flutter将来趋势
目前Flutter主要在移动端Android/iOS双端跨端,Flutter 的愿景是成为一个多端运行的 UI 框架,可以支持不只仅是移动端,还包括Web、桌面、甚至嵌入式设备。在2019 Google I/O 开发者大会上推出的使用 Flutter 开发 Web 应用的框架,同年9月发布Flutter 1.9,并将Flutter web合入Flutter主仓库。
从架构图看,Flutter采用同一个Dart Framework层来统一Flutter C++引擎和Web引擎,最终能够运行在Android,iOS,Browser上,从Flutter引擎代码不难看出Flutter也是支持Fuchsia操做系统。
Fuchsia是Google内部正在开发的一款新的操做系统,采用Flutter做为系统默认的UI框架,也就是说Flutter自然支持Fuchsia,这无疑让Flutter在众多的跨平台方案更有优点。
从Fuchsia技术架构来看,内核层zircon的基础LK是专为嵌入式应用中小型系统设计的内核,代码简洁,适合嵌入式设备和高性能设备,好比IOT、移动可穿戴设备等,目前这些领域尚未标准化级别的垄断者。以及在框架层中有着语音交互、云端以及智能化等模块,由此笔者揣测将来Fuchsia率先应用在音控等智能嵌入式设备。
目前你们广泛比较看好的将来两个技术就是5G和IoT时代。对于5G的需求,很大程度上是由于移动互联网发展到“IoT时代”的阶段。这个发展阶段,全球上网设备的数量可能会达到500亿个。随着5G+IOT时代的到来,如今你们比较关注的Flutter包大小也一样再也不是一个问题,或许Flutter技术的生命期比客户端更长,或许Fuchsia正在驰骋IOT疆场,你所掌握的Flutter技术栈能够无缝迁移,一次弯道超车的机会。
到此,介绍完跨平台技术演进以及Flutter的优点。看到这,相信你可能对Flutter技术有必定兴趣,为了能让你们快速了解Flutter内部原理而不枯燥,Gityuan经过一系列图来帮你们从总体架构来快速理解Flutter。
1. Flutter技术架构
先来看看Flutter总体的技术架构,分为四层,从上之下依次是Dart APP,Dart Framework, C++ Engine,Platform。
Flutter架构最核心的即是Framework(框架)和Engine(引擎):
2. Flutter编译产物
看完Flutter内部架构,或许你好奇,Flutter不用Android/iOS的本地语言技术开发,Dart编写完的代码如何让不一样系统能够识别,最终编译后获得的产物是什么呢?
Flutter产物分为Dart业务代码和Engine代码各自生成的产物,图中的Dart Code包含开发者编写的业务代码,Engine Code是引擎代码,若是并无定制化引擎,则无需从新编译引擎代码。
一份Dart代码,可编译生成双端产物,实现跨平台的能力。通过编译工具处理后可生成双端产物,图中即是release模式的编译产物,Android产物是由vm、isolate各自的指令段和数据段以及flutter.jar组成的app.apk,iOS产物是由App.framework和Flutter.framework组成的Runner.app。
这个过程涉及frontend_server、gen_snapshot、xcrun、ninja编译工具。frontend_server前端编译器会进行词法分析、语法分析以及相关全局转换等工做,将dart代码转换为AST(抽象语法树),并生成app.dill格式的dart kernel。gen_snapshot通过CHA、内联等一系列执行流的优化,根据中间代码生成优化后的FlowGraph对象,再转换为具体相应系统架构(arm/arm64等)的二进制指令。
3. Flutter引擎启动
既然了解了Flutter的编译产物,那你或许又好奇,Flutter这台引擎如何发动的,怎么跟Native衔接呢?
这里以Android为例,熟悉Android的开发者,应该都了解APP启动过程,会执行Application和Activity的onCreate()方法,FlutterApplication和FlutterActivity的onCreate()方法正是链接Native和Flutter的枢纽。
Flutter引擎启动中会建立有4个TaskRunner以及建立虚拟机,分别来看看它们的工做原理。
4. TaskRunner工做原理
Flutter引擎启动过程,会建立UI/GPU/IO这3个线程,会为这些线程依次建立MessageLoop对象,启动后处于epoll_wait等待状态。对于Flutter的消息机制跟Android原生的消息机制有不少类似之处,都有消息(或者任务)、消息队列(或任务队列)以及Looper;有一点不一样的是Android有一个Handler类,用于发送消息以及执行回调方法,相对应Flutter中有着相近功能的即是TaskRunner。
上图是从源码中提炼而来的任务处理流程,比官方流程图更容易理解一些复杂流程的时序问题,后续会专门讲解个中起因。Flutter的任务队列处理机制跟Android的消息队列处理相通,只不过Flutter分为Task和MicroTask两种类型,引擎和Dart虚拟机的事件以及Future都属于Task,Dart层执行scheduleMicrotask()所产生的属于Microtask。
每次Flutter引擎在消费任务时调用FlushTasks()方法,遍历整个延迟任务队列delayed_tasks_,将已到期的任务加入task队列,而后开始处理任务。
可简单理解为先处理完全部的Microtask,而后再处理Task。由于scheduleMicrotask()方法的调用自身就处于一个Task,执行完当前的task,也就意味着立刻执行该Microtask。
了解了其工做机制,再来看看这4个Task Runner的具体工做内容。
5. Dart虚拟机工做
Flutter引擎启动会建立Dart虚拟机以及Root Isolate。DartVM自身也拥有本身的Isolate,彻底由虚拟机本身管理的,Flutter引擎也没法直接访问。Dart的UI相关操做,是由Root Isolate经过Dart的C++调用,或者是发送消息通知的方式,将UI渲染相关的任务提交到UIRunner执行,这样就能够跟Flutter引擎相关模块进行交互。
何为Isolate,从字面上理解是“隔离”,isolate之间是逻辑隔离的。Isolate中的代码也是按顺序执行,由于Dart没有共享内存的并发,没有竞争的可能性,故不须要加锁,也没有死锁风险。对于Dart程序的并发则须要依赖多个isolate来实现。
图解:
6. Widget架构概览
Flutter引擎启动后执行Dart业务,是经过runApp(Widget app)方法,那Widget又是什么呢?
Widget是全部Flutter应用程序的基石,Widget能够是一个按钮,一种字体或者颜色,一个布局属性等,在Flutter的UI世界可谓是“万物皆Widget”。常见的Widget子类为StatelessWidget(无状态)和StatefulWidget(有状态);
三棵树
图解:
可见,开发者经过Widget配置,Framework经过比对Widget配置来更新Element,最后调度RenderObject Tree完成布局排列和绘制。
7. 渲染原理
Dart的UI采用Widget来实现,最终转换为RenderObject,那界面又是如何渲染的呢?
渲染过程,UI线程完成布局、绘制操做,生成Layer Tree;GPU线程执行合成并光栅化后交给GPU来处理,其中几个关键步骤:
GPU线程经过skia向GPU硬件绘制一帧的数据,GPU将帧信息保存到FrameBuffer里面,而后视频控制器会根据VSync信号从FrameBuffer取帧数据传递给显示器,从而显示出最终的画面。
8. Platform Channels
Flutter框架提供了UI的控件支持,对于APP除了UI还有其余依赖于Native平台的支持,好比调用Camera的功能,该怎么办呢?为此,Flutter经过提供Platform Channel的功能,使得Dart代码具有与Native交互的能力。
Platform Channel用于Flutter与Native之间的消息传递,整个过程的消息与响应是异步执行,不会阻塞用户界面。Flutter引擎框架已完成桥接的通道,这样开发者只需在Native层编写定制的Android/iOS代码,便可在Dart代码中直接调用,这也就是Flutter Plugin插件的一种形式。
笔者(Gityuan)以前一直从事于Android操做系统底层研发工做,今年刚接触Flutter,Flutter做为一门全新的跨平台技术框架,不断深究会发现这是一个小型系统,涉及到的技术很广:
这些疑问在前面都逐一简要解答,若是仅仅是用Flutter作业务开发,并不须要掌握这么深度技术,不过,知其然知其因此然,能让你游刃有余。
本文同步在个人公号《跨平台技术演进及Flutter将来》,另外为你们建立了Flutter微信交流群,想加入可添加Gityuan微信好友,备注flutter便可,如发现任何文章有问题欢迎你们直接跟我反馈。
启动篇
通讯篇
渲染篇
后续笔者将持续研究与梳理Flutter内部机制的文章。
如今都说互联网寒冬,其实只要自身技术能力够强,我们就不怕!我这边专门针对Android开发工程师整理了一套【Android进阶学习视频】、【全套Android面试秘籍】、【Android知识点PDF】。若有须要获取资料文档的朋友,能够点击个人GitHub免费获取!