Flutter移动端跨平台框架大解密:优点有哪些?

2019年9月5日19:02:43 发表评论 253 views

Flutter是谷歌的移动端UI开源框架,2018年2月27日, Google发布了Flutter的第一个Beta版本。它是Google使用Dart语言开发的移动应用开发框架,使用Dart代码构建高性能、高保真的iOS和Android应用程序。Flutter的工具和库可以帮助开发者轻松地将自己的想法带到 iOS 和Android 设备上。如果没有任何移动开发经验,用Flutter来构建漂亮的移动应用是不错的选择。

Flutter优点有哪些?

  • 热重载(Hot Reload),利用提供的IDE直接保存代码并重载,手机或者模拟器立马就可以看见效果,这一点调试起来很方便。
  • Widget的理念,对于Flutter来说,手机应用里的所有组件都是Widget,通过可组合的空间集合、丰富的动画库以及分层可扩展的架构实现了富有感染力的灵活界面设计。
  • 借助GPU加速的渲染引擎以及高性能本地代码运行时以达到跨平台设备的高质量用户体验。

现有的移动平台:

苹果的iOS SDKs发布于2008年,谷歌的Android软件开发工具包发布于2009年,这两种sdk包是基于不同的编程语言的,分别是Objective-C和Java, 如下是大概的结构图:

Flutter移动端跨平台框架大解密:优点有哪些?

所以带来的问题是大多数APP要针对不同系统提供不同版本的应用,因为系统提供的组件和语言不一样。随之而来的问题是如何只开发一套代码,两端都可以运行,也就有了如下的三代跨端平台的出现。

WebView

这是第一个跨平台的框架,基于JavaScript 和 WebView 例如 Cordova、PhoneGap、APPCan、Ionic等,应用程序可以编写成Html,并最终在移动平台的Webview中显示,并通过JavaScript interface和原生交互。

缺点:

  • 加载性能慢,达不到原生UI的体验;
  • 内存消耗比较大;
  • 手势/动画和原生差距比较大;
  • 相关原生功能支持有限。
" data-data-original="https://user-gold-cdn.xitu.io/2019/7/24/16c21e8ad21d46c0?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" src="http://www.cainiaoxueyuan.com/wp-content/themes/begin/img/blank.gif" alt="Flutter移动端跨平台框架大解密:优点有哪些?" data-width="830" data-height="146" />

响应式视图

原生体验的第二代跨平台框架,如ReactNative/Weex,生成虚拟DOM,并进一步对应生成原生的组件,让页面由原生组件组成,来到达原生的体验。JS代码和原生代码本身都是很快的,瓶颈经常发生在当我们视图从一边转向另一边时,所以构建高质量的应用程序时,我们必须将使用桥接的次数控制到最小。

缺点:

  • 虚拟DOM和原生组件的沟通需要Bridge;
  • 一些复杂的交互组件和动画性能上表现并达不到原生;
  • 平台之间的兼容性问题。
Flutter移动端跨平台框架大解密:优点有哪些?

Flutter

第三代跨平台框架,Flutter也提供响应式的视图,Flutter采用不同的方法避免由JavaScript桥接器引起的性能问题,即用名为Dart的程序语言来编译,Dart是用预编译的方式编译多个平台的原生代码,这允许Flutter直接与平台通信,同时使用Skia图形引擎来完成图形、文本、图像、动画等绘制,拥有自己独立的一套图形系统,不再依赖于原生。

缺点:

  • 学习成本较高;
  • 依赖库较大;
  • 目前版本处于beta版。
Flutter移动端跨平台框架大解密:优点有哪些?

Flutter 架构

Flutter移动端跨平台框架大解密:优点有哪些?

这种分层设计的目的是帮助开发者写更少的代码来实现功能。例如,Material层通过组合Widget层的控件来构建,而Widget层本身则依赖Rendering层来构建。上述分层为我们开发App提供了很多选择,首先可以使用Flutter提供的现有Widget来组合,或者创建自定义的Widget。

Widget

开发者通过实现一个build函数来定义一个Widget,这个build函数会返回一个Widget树,这棵Widget树更具体地描述了UI中的Widget层次。例如,一个ToolBar Widget的build函数可能会返回一个水平布局、一些文本和不同的按钮,框架会递归地调用每个Widget的build函数,直到所有的Widget都遍历完成,然后将这些Widget组合成一颗Widget树。

交互

如果Widget的特性基于用户交互或其他因素进行改变,则这个Widget是有状态的,Flutter提供两种类型的widget, StatelessWidget/StatefulWidget,前者为状态不可变,后者可以通过setState()改变state来改变更新UI,开发者可以根据自己的实际情况使用 StatefulWidget:

Flutter移动端跨平台框架大解密:优点有哪些?

StatelessWidget:

Flutter移动端跨平台框架大解密:优点有哪些?

Widget布局方式:

在Android系统中,我们通常是使用xml来进行UI布局,同时可以通过addChild和removeChild添加或者移除视图。 但是在Flutter中,Widget 是不可变的,可以传入一个函数,该函数返回一个子Widget 给父 Widget。并在该函数中通过一个 bool 值来控制子 Widget 的创建。

Touch事件监听:

Flutter中有两种方式来处理touch:

  1. 直接传递一个处理事件的方法给Widget;
  2. 通过GestureDetector来实现事件监听与处理。
  • Tap(onTapDown/ onTapUp/ onTap/ onTapCancel)
  • Double tap(onDoubleTap)
  • Long press(onLongPress)
  • Vertical drag(onVerticalDragStart/ onVerticalDragUpdate/ onVerticalDragEnd)
  • Horizontal drag(onHorizontalDragStart/ onHorizontalDragUpdate/ onHorizontalDragEnd)
Flutter移动端跨平台框架大解密:优点有哪些?
Flutter移动端跨平台框架大解密:优点有哪些?

动画:

在 Android 中我们能用View.animate()来启动一个动画,在Flutter中我们是把Widget包在Animation中。在 Flutter中,有AnimationController 和Interpolator来控制动画的启动。

Flutter移动端跨平台框架大解密:优点有哪些?
Flutter移动端跨平台框架大解密:优点有哪些?

Canvas:

在 Android 中 我们能使用Canvas来画或者定制一些UI。在 Flutter中,有CustomPaint 和 CustomPainter来提供一些算法完成绘画功能。

Flutter移动端跨平台框架大解密:优点有哪些?

自定义Widget:

在 Android 中 我们通过继承实现View/ViewGroup等组件来完成一些自定义的组件,在 Flutter中,不提供继承这种方式,而是通过一些小的组件组合。

Flutter移动端跨平台框架大解密:优点有哪些?

页面切换:

在 Android 中 我们通过Intents的方式来启动页面或者service,在 Flutter中没有Intent, 我们就需要route 和 Navigator来管理页面了,Route可以当作一个page或者activity,Navigator 是一个widget用来管理routes的,能push或者pop页面。

Flutter移动端跨平台框架大解密:优点有哪些?
Flutter移动端跨平台框架大解密:优点有哪些?

原生生命周期监听:

在android中,页面的生命周期都在activity和fragment中控制,但是Flutter只有一个FlutterView, 我们需要hook WidgetsBinding 的observer并监听didChangeAppLifecycleState的event消息。

Flutter移动端跨平台框架大解密:优点有哪些?

页面间参数传递:

Flutter 页面切换是通过Router和Navigator完成的,同样可以通过result back的方式获取你push的router返回的数据。

Flutter移动端跨平台框架大解密:优点有哪些?
Flutter移动端跨平台框架大解密:优点有哪些?

和原生之间的数据交互

Flutter 是支持原生页面和Flutter页面混合开发的,但是不支持原生组件在Flutter中使用,原生端有methodchannel 来支持Flutter对原生的一些API调用。

Flutter移动端跨平台框架大解密:优点有哪些?
Flutter移动端跨平台框架大解密:优点有哪些?

网络请求

在Andorid中,我们有很多类似Okhttp之类的网络使用,非常方便,在Flutter中,我们使用http package来简单的完成一个网络请求调用。

Flutter移动端跨平台框架大解密:优点有哪些?

Flutter UI组件

Flutter 内置有很多 Material Design 和 Cupertino(iOS 风格)的部件、丰富的手势 API、自然平滑的滑动动画

  • ListView/GridView/ViewPager/Card …
  • Row/Column/Stack等等的布局
  • import 'package:flutter/material.dart'

其他功能:

Android端设计分析:

UI

从Android端页面层次来看,主页面MainActivity是继承了FlutterActivity,通过FlutterActivityDelegate控制一些初始化,包括FlutterView,而整个Flutter展示的页面是绘制在FlutterView中的。

Flutter移动端跨平台框架大解密:优点有哪些?

Flutter跨平台的基础就是UI跨平台,UI绘制不依赖系统组件, FlutterView将Dart编写的界面封装成android平台可以使用的组件,这个组件完成了android应用界面的所有绘制工作,ios也有相同的一套机制,从而实现了不同平台共用一套绘制界面的代码。

FlutterView继承了SurfaceView,从API中可以看出SurfaceView属于View的子类,提供双缓存功能,它是专门为制作游戏而产生的,功能非常强大,最重要的是它支持OpenGL ES库,2D和3D的效果都,既然Flutter界面是直接继承于SurfaceView的,它的绘制过程就不再依赖于系统平台,解耦了系统控件的调用。

Flutter的消息系统:

采用MethodChanel实现7个消息模块管理:多语言、路由导航、按键消息、生命周期、系统信息、用户设置和平台插件,这几乎涵盖了不同平台所有差异化最大的功能,而且非常依赖原生系统。

Flutter移动端跨平台框架大解密:优点有哪些?

MethodChanel:

Flutter移动端跨平台框架大解密:优点有哪些?

下面我们以keyevent为例子简单说明事件传递机制:

Flutter移动端跨平台框架大解密:优点有哪些?

FlutterView类有两个处理按键事件的接口,一个是onKeyUp(),一个是onKeyDown(),分别对应按键松开和按下事件,两个方法流程一样,Flutter再将平台的按键事件以消息方式拦截,具体步流程建议参考源码:

  • system_channels.dart
  • raw_keyboard.dart
  • raw_keyboard_listener.dart

Flutter 、ReactNative、原生的比较分析:

UI 层次比较:

可以看到Flutter架构里面只有一个FlutterView用来呈现所有的widget的布局的,所以整个渲染过程是独立于原生UI,而ReactNative和原生是比较类似的,会将js中的UI组件一一对应到原生组件。

Flutter UI层次:

Flutter移动端跨平台框架大解密:优点有哪些?

ReactNative UI层次:

Flutter移动端跨平台框架大解密:优点有哪些?

内存/cpu/gpu分析:

我们做了一个简单demo,测试滑动一个有100条数据的list,内存上Flutter和原生相差不大,比较稳定,ReactNative内存波动比较大。CPU方面Flutter比较原生高了接近两倍,相比ReactNative也明显要高。GPU方面Flutter除了初始化时GPU比较高,应该是初始化FlutterView,后面的拖动过程中看不到GPU的渲染,原因应该是独立的渲染体系,android studio 提取不出来。所以整体而言原生的性能是最佳的。

Flutter性能:

Flutter移动端跨平台框架大解密:优点有哪些?

ReactNative性能:

Flutter移动端跨平台框架大解密:优点有哪些?

原生性能:

Flutter移动端跨平台框架大解密:优点有哪些?

APK大小分析:

Flutter debug包下,lib库包含86_64/x86/armeabi-v7a,接近50M,考虑现在的手机支持X86比较少,在release包中只包含了armeabi-v7a,lib库大小压缩到了3.3M,整个APK压缩后将在7.5M左右,其他资源大部分是Flutter的代码,主要集中在assets下,而且有优化空间。 相比较于ReactNative,本身的SDK库在3.5M左右,简单的页面对应的JS包大小在300K左右,占用空间能减少不少,但是Flutter是自己实现的一套engine,完全独立于系统平台,占用比较大,其实也能理解。

Flutter apk结构:

Flutter移动端跨平台框架大解密:优点有哪些?

ReactNative apk结构:

Flutter移动端跨平台框架大解密:优点有哪些?

原生结构:

Flutter移动端跨平台框架大解密:优点有哪些?

性能比较分析:

ReactNative是基于前端思想开发的框架,对于原生复杂的ListView/Gridview等容器,没有办法直接实现,而且还有些复杂的UI依赖于View的嵌套叠加,在这种设计,相比较原生的设计,就会多出很多的View,相比native 实现来说会多很多view对象,造成了性能降低。也就是说复杂UI需求下,RN对UI的表达效率远低于native,造成性能低下。Flutter是基于Skia自己实现的UI组件库,所以在布局和动画层次上有跟多的灵活性和性能优化空间,可以做到最优化。

开发语言上, js或dart都是一种声明式的写法,但js需要解释,dart是直接语言层面支持了node tree的书写,且对象创建成本低,可直接编译成native代码(AOT),VM效率更高,所以运行上dart效率高很多, 而且Dart 是一种同时支持 JIT/AOT 编译的语言,JIT 开发模式时能快速编译生效,是Hot Reload体验的关键。

兼容性分析:

Flutter所提供的所有的widget/动画还有事件机制都是基于skia来实现的,与平台无关,所以有很高的跨平台的兼容性。但是独立的UI系统导致了,很多Android/iOS对应的工具无法使用。

ReactNative所有的组件都是依赖于原生的,而Android/iOS本身的组件和实现就不一样,导致了很多兼容性问题,不同平台要做适配和桥接,导致了很多的功能成本/开发成本和性能牺牲,比如动画/手势/数据容器等等。

适配性:

Flutter 提供的widget都是基于skia来实现和精心定制的,与具体平台没关,所以能保持很高的跨平台的兼容性,对未来平台的适应性上Flutter从更基础的层去抹平平台差异,Flutter站在了更宽广、更可控的一个基础平台上去演变和发展。ReactNative永远需要follow native开发的这套约束,桥接和抹平差异乃至应用层去适配的成本、面对具体场景去优化性能所需要的成本都是居高不下的。

Flutter引擎+Dart语言将很有可能成为Google Fuchsia系统主要的UI开发框架, 这将会将其跨平台的特性发挥的淋漓尽致。

Flutter 不足的地方:

  • 开发语言是基于Dart, 对开发者而言,增加了不少学习成本
  • UI布局方面,层次不够明显,不如原生xml写法那么直接,复杂化了程序的可读性
  • Flutter是一种新的框架,目前市面上应用和社区不太成熟,而且支持的库不如ReactNative及原生
  • 目前Dart代码会AOT编译到native,不像ReactNative,支持热更新起来会很难,但从API的结构设计上来看,后期应该很快会实现热更新
  • 不能支持原生组件在Flutter中显示,导致很多组件需要重新开发,不如ReactNative灵活

总之从Flutter的设计理念来看,整体架构都是具有革命性的,相比于其他跨平台实现了真正意义的跨平台,各平台体验一致,而且让用户体验达到了最优,各种UI库和组件也在不断的增加,各种生态系统和社区在不断的完善,对于以后新的操作系统适配性会更强,如Fuchsia系统,非常值得大家了解和学习,相信不久的将来,会慢慢成熟起来,成为主流开发语言。

ARES团队也在持续保持更新,未来会和JDReact引擎一起成为京东多端融合平台的双引擎。

作者:ARES
链接:https://juejin.im/post/5d37c84e6fb9a07ee0635978
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: