Author | Yuan Huihui
Zebian |
Guo Rui
Cross-platform mobile technology evolution
1 Introduction
Mobile Internet development ten years, along with the growing popularity of Android, iOS and other smart phones, mobile terminal has been gradually replaced by the PC has become a battleground. So-called "end of the world to those who have to move," mobile terminal has become the largest Internet traffic entrance areas of distribution, a large number of Internet companies is the rise in this trend.
2. Why do you need a cross-platform technology?
With the rapid development of mobile Internet, the company more competitive, how fast landing a good idea, rapid trial and error, has become a major concern. Enhance R & D efficiency and shorten the development cycle to ensure rapid product trial and error and can rapidly iterate new feature that allows new products and features at the same time to arrive as quickly as Android, iOS and other multi-terminal user.
As we all know, Android applications written in Java or Kotlin, iOS applications using Objective-C or Swift writing, Web terminal using HTML / CSS / JavaScript written. When you need to support the development of multi-terminal applications, each end requires a separate development, testing, all the way to the line, as well as ongoing maintenance workload up to a doubling, bound to extend the development cycle.
In order to solve the problem multiport independent development, cross-platform technology will come into being, the major Internet companies have invested a lot of manpower for this purpose, so there is a variety of cross-platform technology framework, emerging cross-platform technical solutions in the face of the mobile space, and Selection of technology going to help it?
3. Mobile terminal technology selection
Cross-end technical solutions as the mobile side, concerns nothing less than the following four areas: R & D efficiency, dynamic, multi-terminal consistency, performance experience.
4. 跨平台技术划分
对研发效率和体验的不断追逐,移动端的跨平台技术方框架层出不穷,然则天下武功众多,万变不离其宗,从其核心本质来划分,可大致分为以下三大类:
5. 跨平台技术演进
跨平台技术,一直以来是每一个有追求的开发者所追逐的梦想,同时也是守旧者的噩梦,跨平台的多端一体化方案势必颠覆现有的原生各端独立开发模式,接下来列举众多的跨平台技术中最为关键的几个技术方案的演进阶段。
从上图可以看出,技术演进过程大致分以下三个阶段:
面对现有的如此多跨平台方案,为何当下最火的跨平台技术是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要素,研发效率、动态性、多端一致性、性能体验,分别对应下面这一组词语。
图解:
Android原生框架,通过调用Java Framework层,再调用到skia来渲染界面;
其他跨平台方案(如RN),通过JSBridge中间层来将JS写的APP转换成相应的原生渲染逻辑,可见比Native代码增加了更多逻辑,性能逊色差于原生框架;
Flutter框架,APP通过调用Dart Framework层,再直接调用到skia来渲染界面,并没有经过原生Framework过程,可见其渲染性能并不会弱于Native技术,这是一个性能上限很高的跨平台技术。
当然,不得不说目前的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技术架构来看,内核层zircon的基础LK是专为嵌入式应用中小型系统设计的内核,代码简洁,适合嵌入式设备和高性能设备,比如IOT、移动可穿戴设备等,目前这些领域还没有标准化级别的垄断者。以及在框架层中有着语音交互、云端以及智能化等模块,由此笔者揣测未来Fuchsia率先应用在音控等智能嵌入式设备。
目前大家普遍比较看好的未来两个技术就是5G和IoT时代。对于5G的需求,很大程度上是因为移动互联网发展到“IoT时代”的阶段。这个发展阶段,全球上网设备的数量可能会达到500亿个。随着5G+IOT时代的到来,现在大家比较关注的Flutter包大小也同样不再是一个问题,或许Flutter技术的生命期比客户端更长,或许Fuchsia正在驰骋IOT疆场,你所掌握的Flutter技术栈可以无缝迁移,一次弯道超车的机会。
到此,介绍完跨平台技术演进以及Flutter的优势。看到这,相信你可能对Flutter技术有一定兴趣,为了能让大家快速了解Flutter内部原理而不枯燥,本文不放任何的源码,通过一系列图来帮大家从整体架构来快速理解Flutter。
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。
这个过程涉及frontendserver、gensnapshot、xcrun、ninja编译工具。frontendserver前端编译器会进行词法分析、语法分析以及相关全局转换等工作,将dart代码转换为AST(抽象语法树),并生成app.dill格式的dart kernel。gensnapshot经过CHA、内联等一系列执行流的优化,根据中间代码生成优化后的FlowGraph对象,再转换为具体相应系统架构(arm/arm64等)的二进制指令。
3. Flutter引擎启动
既然了解了Flutter的编译产物,那你或许又好奇,Flutter这台引擎如何发动的,怎么跟Native衔接呢?
这里以Android为例,熟悉Android的开发者,应该都了解APP启动过程,会执行Application和Activity的onCreate()方法,FlutterApplication和FlutterActivity的onCreate()方法正是连接Native和Flutter的枢纽。
FlutterApplication.java的onCreate过程主要完成初始化配置、加载引擎libflutter.so、注册JNI方法;
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()方法,遍历整个延迟任务队列delayedtasks,将已到期的任务加入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来实现。
图解:
isolate堆是运该isolate中代码分配的所有对象的GC管理的内存存储;
vm isolate是一个伪isolate,里面包含不可变对象,比如null,true,false;
isolate堆能引用vm isolate堆中的对象,但vm isolate不能引用isolate堆;
isolate彼此之间不能相互引用;
每个isolate都有一个执行dart代码的Mutator thread,一个处理虚拟机内部任务(比如GC, JIT等)的helper thread;可见,isolate是拥有内存堆和控制线程,虚拟机中可以有很多isolate,但彼此之间内存不共享,无法直接访问,只能通过dart特有的Port端口通信;isolate除了拥有一个mutator控制线程,还有一些其他辅助线程,比如后台JIT编译线程、GC清理/并发标记线程。
6. Widget架构概览
Flutter引擎启动后执行Dart业务,是通过runApp(Widget app)方法,那Widget又是什么呢?
Widget是所有Flutter应用程序的基石,Widget可以是一个按钮,一种字体或者颜色,一个布局属性等,在Flutter的UI世界可谓是“万物皆Widget”。常见的Widget子类为StatelessWidget(无状态)和StatefulWidget(有状态):
三棵树
图解:
Widget是为Element描述需要的配置, 负责创建Element,决定Element是否需要更新。Flutter Framework通过差分算法比对Widget树前后的变化,决定Element的State是否改变。当重建Widget树后并未发生改变, 则Element不会触发重绘,则就是Widget树的重建并不一定会触发Element树的重建。
Element表示Widget配置树的特定位置的一个实例,同时持有Widget和RenderObject,负责管理Widget配置和RenderObject渲染。Element状态由Flutter Framework管理, 开发人员只需更改Widget即可。
RenderObject表示渲染树的一个对象,负责真正的渲染工作,比如测量大小、位置、绘制等都由RenderObject完成。
可见,开发者通过Widget配置,Framework通过比对Widget配置来更新Element,最后调度RenderObject Tree完成布局排列和绘制。
7. 渲染原理
Dart的UI采用Widget来实现,最终转换为RenderObject,那界面又是如何渲染的呢?
渲染过程,UI线程完成布局、绘制操作,生成Layer Tree;GPU线程执行合成并光栅化后交给GPU来处理,其中几个关键步骤:
Animate: 遍历_transientCallbacks,执行动画回调方法;
Build: 对于dirty的元素会执行build构造,没有dirty元素则不会执行,对应于buildScope()
Layout: 计算渲染对象大小和位置,对应于flushLayout(),这个过程可能会嵌套再调用build操作;
Compositing bits: 更新具有脏合成位的任何渲染对象, 对应于flushCompositingBits();
Paint: 将绘制命令记录到Layer, 对应于flushPaint();
Compositing: 将Compositing bits发送给GPU, 对应于compositeFrame()。
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插件的一种形式。
结束语
科技不断在进步,技术不断发展,移动跨平台技术几乎从Android、iOS诞生不久便出现,已发展快10年。时至今日,兼具跨端高效率与高性能体验的Flutter力压群雄,崭露头角,已然成为当下最热门的移动端新技术,全球越来越多的公司在Flutter技术布局并落地产品应用,社区也非常活跃。
笔者之前一直从事于Android操作系统底层研发工作,今年刚接触Flutter,Flutter作为一门全新的跨平台技术框架,不断深究会发现这是一个小型系统,涉及到的技术很广:
编译技术如何将dart代码转换为AST(抽象语法树),如何汇编转换为机器码,打包成产物是什么?
Flutter这台引擎如何发动的,怎么跟Native原生系统衔接运行,如何识别产物并加载到内存?
引擎启动后,TaskRunner如何分发任务,跟原生系统消息机制有什么关系?
Dart虚拟机如何管理内存,跟isolate又有什么关系?
开发者编写的Widget控件如何渲染到屏幕上?
Flutter如何通过plugin支持移动设备提供的服务?
In this paper these questions are answered one by one, if only to do with Flutter business development, so do not need to know the depth of technology, however, know these know why, make you at ease. This article describes cross-platform technology of the past and the future, and the interpretation of the principle of internal Flutter From a macro framework, follow-up time for more in-depth technical details and practical experience perspective Secret more Flutter technology with you.
With the arrival of 5G + IOT era, Fuchsia system may force IOT new battlefield, you have to master the technology stack can Flutter seamless migration, this is a chance of overtaking around the curve. Even Fuchsia defeat, I believe that as long as the essence of deep tie Flutter system technology, mobile end any other new technology can quickly and easily grasp.
Finally, a word to the end of this share, "Sometimes, you choose a direction, not because it will be the future, but it may become a different future."
Author: Yuan Huihui, Andrews well-known bloggers, CSDN bloggers "Gityuan " keen to study Android system architecture and core technology has a profound understanding and rich experience of the Android framework.
Scanning the next Fanger Wei code, see bloggers to share more exciting!
【END】
Thermal paper recommended
Why is Google, Microsoft, Huawei will put a one hundred million source code repository?
☞
Click here to read the original participation questionnaire, Gifts to send non-stop!
Your point of each "look", I seriously as a favorite