解密的Flutter跨平台移动框架:有什么好处?
Flutter 是 Google 的开源移动用户界面框架。 2018年2月27日,谷歌发布了Flutter的第一个测试版。它是Google使用Dart语言开发的移动应用程序开发框架。它使用 Dart 代码构建高性能、高保真 iOS 和 Android 应用程序。 Flutter 的工具和库可帮助开发人员轻松地将他们的想法带到 iOS 和 Android 设备上。如果你没有移动开发经验,使用 Flutter 构建漂亮的移动应用是一个不错的选择。
Flutter 有哪些优势?
- 热重载,使用附带的IDE直接保存代码并重新加载。在手机或者模拟器上立即可以看到效果,调试起来非常方便。
- 小工具的概念。对于 Flutter 来说,移动应用中的所有组件都是 widget。通过组合的空间集合、丰富的动画库以及分层和可扩展的架构,实现了富有感染力和灵活的界面设计。
- 借助 GPU 加速渲染引擎和高性能本机代码执行时间,在平台设备上实现高质量的用户体验。
现有的移动平台:
Apple的iOS SDK于2008年发布,Google的Android SDK于2009年发布。这两个SDK基于不同的编程语言,即Objective-C和Java,以下是大致的结构图:
所以问题是,大多数APP需要为不同的系统提供不同版本的应用程序,因为系统提供的组件和语言不同。由此产生的问题是如何开发出一套可以在两端运行的代码,这也就催生了接下来的三代跨平台。
WebView
这是第一个基于JavaScript和WebView的跨平台框架,例如Cordova、PhoneGap、APPCan、Ionic等。该应用程序可以用 Html 编写,最终显示在移动平台的 Web 视图中,并处理 JavaScript 界面和本机交互。
缺点:
- 加载慢,无法达到原来的UI体验;
- 内存消耗比较高;
- 动作/动画与原生差距较大;
- 对相关原生功能的支持有限。
响应式视图
ReactNative/Weex等第二代跨平台原生体验框架创建虚拟DOM并进一步相应的生成原生组件,让页面由原生组件组成,达到原生的体验,无论是JS代码还是原生代码本身都很快,但是瓶颈往往出现在我们的视图从一个页面转到另一个页面的时候,所以我们制作高质量应用程序时需要将桥的数量限制到最少。跨平台兼容性。问题是使用一种名为 Dart 的编程语言来编译。 Dart 使用预编译的方法来编译多个平台的源代码。这使得Flutter可以直接与平台通信,并使用Skia图形引擎来完成图形、文本和图像。 、动画等绘图,拥有自己独立的图形系统,不再依赖原生。
缺点:
- 学习成本较高;
- 庞大的依赖库;
- 当前版本处于测试阶段。
Flutter架构
这种分层设计旨在帮助开发者编写更少的代码来实现功能。例如,材质层是通过组合widget层控件构建的,而widget层本身又依赖于渲染层。建造它。上层的分层给了我们应用开发很多的可能性。首先,我们可以使用 Flutter 提供的现有 widget 来组合或创建自定义 widget。
Widget
开发人员通过实现小部件来定义构建器函数,该构建器函数返回一个小部件树,详细说明了用户界面中小部件的层次结构。例如,工具栏小部件构建器函数可能返回水平布局、一些文本和各种按钮。框架会递归调用每个widget的构建函数,直到遍历完所有widget,然后将这些widget合并成一个widget。一颗树。
交互
如果小部件特性根据用户交互或其他因素发生变化,则小部件是有状态的。 Flutter 提供了两种类型的 widget,StatelessWidget/StatefulWidget。第一个是无状态的,第二个可以通过 setState() 更改状态来更改和更新 UI。开发者可以根据自己的实际状态来使用StatefulWidget:
StatelessWidget:
Widget布局方式:
在Android中,我们通常使用xml来布局UI,并且可以通过addChild和removeChild来添加或删除视图。但在 Flutter 中,Widget 是不可变的,可以传入将子 Widget 返回给父 Widget 的函数。并在该函数中使用一个bool值来控制子组件的创建。
跟踪触摸事件:
在 Flutter 中处理触摸有两种方法:
- 将事件处理方法直接传递给 Widget;
- 通过GestureDetector实现事件监控和处理。
- 点击(onTapDown/ onTapUp/ onTap/ onTapCancel)
- 双击(onDoubleTap)
- 长按(onLongPress)
- 垂直拖动(onVerticalDragStart/ onVerticalDragUpdate / onVerticalDragEnd)
- 水平拖动(onHorizontalDragStart/ onHorizontalDragUpdate ) / onHorizontalDragEnd)
动画:
在Android中,我们可以使用View.animate()来启动动画。在 Flutter 中,我们将 widget 包装成动画。在Flutter中,有一个AnimationController和一个Interpolator来控制动画的开始。
Canvas:
在Android中,我们可以使用Canvas来绘制或自定义一些用户界面。在Flutter中,有CustomPaint和CustomPainter提供了一些算法来完成绘画功能。
自定义Widget:
在Android中,我们通过继承实现View/ViewGroup等组件来完成一些自定义组件。在Flutter中,继承并不是通过这种方式提供的,而是通过组合一些小组件来提供的。
页面切换:
在Android中,我们使用意图来启动页面或服务。 Flutter中没有Intent,所以我们需要route和Navigator来管理页面。路由可以用作页面或活动,导航器是用于管理路由的小部件,可以推送或打开页面。
原生生命周期监控:
在Android中,页面生命周期是在activity和fragment中控制的,但Flutter只有一个FlutterView。我们需要连接 WidgetsBinding 观察者并侦听 didChangeAppLifecycleState 事件消息。
在页面之间传输参数:
Flutter 页面切换通过路由器和导航器进行。还可以获取路由器返回的数据。
原生与原生数据交互
Flutter 支持原生和 Flutter 页面混合开发,但不支持在 Flutter 中使用原生组件。首页有一个methodchannel来支持Flutter的一些原生API调用。
网络要求
在Android中我们有很多像Okhttp这样的网络应用程序,非常方便。在Flutter中,我们使用http包来轻松完成一次网络请求调用。
Flutter UI 组件
Flutter 内置了许多 Material Design 和 Cupertino(iOS 风格)组件,具有丰富手势的 API 和自然流畅的滚动动画
- ListView/GridView/ViewPager/Card…
- Row / 列布局/堆栈等
- import 'package:flutter/material.dart'
其他功能:
- 使用 Shared_Preferences 插件 pub.dartlang.org/packages/sh…
- GPS ,使用 https://pub .dartlang。 org/packages/location
- 相机,使用插件 https://pub.dartlang.org/packages/image_picker
- Sqlite,使用 Sqlfile pub.dartlang.org/packages/sq …
- 注意,使用 Firebase_Messaging, github.com/flutter/plu...
Android设计分析:
UI
在Android页面层面,主页面MainActivity继承自FlutterActivity,通过FlutterActivityDelegate控制一些初始化,包括FlutterView,以及整个页面它是由Flutter显示的,它是在FlutterView中绘制的。
Flutter 跨平台性的基础是其跨平台用户界面。用户界面绘图独立于系统组件。 FlutterView 将用 Dart 编写的接口映射为可以在 android 平台上使用的组件。该组件完成了Android应用程序界面绘制的全部工作。 ios也是同样的情况。一套机制,实现不同平台通用的一套绘图接口代码。
FlutterView继承SurfaceView。 API显示SurfaceView是View的子类,提供双缓冲功能。它是专门用来制作游戏的,功能非常强大。最重要的是,它支持 OpenGL ES 库。 2D 和 3D 效果均可用。由于Flutter接口直接继承自SurfaceView,其绘制过程不再依赖于系统平台,从而分离了系统控制调用。
Flutter的消息系统:
使用MethodChanel实现多语言、路由导航、关键消息、生命周期、系统信息、用户设置和平台插件7个消息模块的管理,几乎涵盖了不同平台的所有差异。最大的特点是严重依赖于本机系统。 ?打开事件和按下事件,两种方法的流程是一样的。 Flutter以消息的形式拦截关键平台事件。具体步骤建议参考源码:
- system_channels.dart
- raw_keyboard.dart
- raw_keyboard_listener.dart
Flutter、ReactNative与native对比分析: 用户界面层次对比:
可以看出,在Flutter架构中,只有一个FlutterView代表所有Widget的布局,所以整个渲染过程是独立于原生UI的。 ReactNative与native类似,会将js中的UI组件一一映射到native组件。 ?不大,比较稳定,ReactNative内存波动比较大。在CPU方面,Flutter几乎是原生的两倍,也明显高于ReactNative。在GPE方面,Flutter在初始化时有比较高的GPE。它应该初始化 FlutterView。在后续的拖动过程中看不到GPE渲染。原因应该是Android Studio无法提取出独立的渲染系统。总的来说,国内的表现是最好的。 ?手机支持的X86相对较少。发布包仅包含armeabi-v7a。 lib库的大小被压缩为3.3M,压缩后完整的APK约为7.5M。其他大部分资源都是 Flutter 代码,大部分集中在 asset 下。并且还有优化的空间。与ReactNative相比,其自带的SDK库约为3.5M,一个简单页面对应的JS包大小约为300K,可以大大减少占用空间。而Flutter则是一套自行实现的引擎,完全独立于系统平台,占用大量空间。虽然比较大,但是其实也可以理解。 ?该方法是直接实现的,一些复杂的用户界面依赖于嵌套视图覆盖。与本机设计相比,此设计中会有更多的视图,并且与本机实现相比,也会有更多的视图,从而导致性能下降。也就是说,对于复杂的UI需求,RN UI的表达效率远低于原生,导致性能低下。 Flutter基于Skia自己的UI组件库,因此在布局和动画层面有很大的灵活性和性能优化空间,可以进行优化。
从开发语言的角度来说,js或者dart都是声明式的写作风格,但是js需要一个解释。 Dart直接支持在语言层面编写节点树并且对象创建成本低并且可以直接编译为源代码(AOT),VM效率更高,因此Dart在运行时效率要高得多,而且Dart是支持JIT的语言/ AOT。在JIT开发模式下能够快速编译并生效,这是Hot Reload体验的关键。
兼容性分析:
Flutter提供的所有widget/动画和事件机制都是基于ski实现的,与平台无关,因此具有很高的跨平台兼容性。然而,由于与系统无关的用户界面,许多相应的Android/iOS工具无法使用。
所有ReactNative组件都依赖于原生组件,而Android/iOS组件和实现不同,导致很多兼容性问题。不同的平台需要进行调整和桥接,从而导致大量的功能/开发成本和性能牺牲,例如动画/运动/数据容器等。并仔细适应滑雪的基础。它们与特定平台无关,因此可以保持高度的跨平台兼容性和对未来平台的适应性。 Flutter 在更基础的层面上消除了平台差异,Flutter 在更广泛、更可控的基础平台上不断演进和发展。 ReactNative 必须始终遵循一组原生开发约束。弥合和消除差异,甚至针对特定场景定制应用层和优化性能的成本都很高。
Flutter引擎+Dart语言将极有可能成为Google Fuchsia UI开发的主要框架,充分赋能其跨平台特性。
Flutter的缺点:
- 开发语言基于Dart,增加了开发者大量的学习成本
- 关于用户界面的布局,层次结构不够清晰,没有那么简单由于原来的xml编写,程序的可读性比较复杂
- Flutter是一个新的框架。目前市场上的应用程序和社区都不是很成熟,支持的库不如ReactNative和原生
- 目前Dart AOT代码会编译为原生,与ReactNative不同。支持热更新会有一定难度,但考虑到API的结构设计,热更新应该很快就会推出。没有ReactNative那么灵活
总之,就Flutter的设计理念而言,整个架构是革命性的。与其他跨平台相比,它实现了真正的跨平台。各平台体验一致,用户体验优化。各种UI库和组件也在不断增加,各种生态系统和社区也在不断完善。未来它们会更加适应Fuchsia等新操作系统,值得了解和学习。相信在不久的将来它会慢慢成熟并成为主流开发语言。
ARES团队也持续更新,未来将与JDReact引擎一起成为京东多终端整合平台的双引擎。
作者:ARES
链接:https://juejin.im/post/5d37c84e6fb9a07ee0635978
来源:掘金
版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明来源。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。