Flutter 进阶之路 ————跨平台架构实现
前言
2015年, Google 内部开始测试另一种高性能的编程方式,那就 Google 的 Sky 项目。Sky 项目使用网页开发语言Dart开发原生Android 应用,强调应用的运行速度和与 Web 的高度集成。Sky将其Web后端也带到了移动开发领域。Sky不依赖于平台,其代码可以运行在Android、iOS,或是任何包含Dart虚拟机的平台上。
可以说sky是Flutter框架的前身。
在 2017年的谷歌 I/O大会上,Google推出了Flutter —— 一款新的用于创建移动应用的开源库。
在2018年初世界移动大会上发布了 Flutter的第一个Beta版本,2018年5月的 I/O大会上更新到了Beta3版本,向正式版又迈进了一步。一时间业内对这个框架的关注度越来越高。
Flutter 是 Google 开源的跨平台移动开发框架。 它允许从单个代码库为 iOS 和 Android 构建高性能,美观的应用程序。它也是 Google 即将推出的 Fuchsia 操作系统的开发平台。此外,它的架构可以通过定制的 Flutter 引擎将其引入其他平台。
1、Flutter诞生的原因
跨平台工具包历来采用以下两种方法之一:
将 Web 视图包装在本机应用程序中,并将应用程序构建为网页。
包装原生平台控件并提供对它们的一些跨平台抽象。
Flutter 采取不同的方法,试图使移动开发更好。 它提供了一个开发人员使用的应用程序框架和一个可移植的运行时引擎。该框架建立在 Skia 图形库上,提供实际呈现的部件,而不仅仅是原生控件的包装。
Flutter 做跨平台开发能够像 web 一样灵活,但同时提供流畅的性能。
Flutter 附带的部件库以及开源部件使其成为一个功能丰富的平台。简单地说,Flutter 是最接近移动开发人员用于跨平台开发的理想平台,灵活性、性能几乎毫无妥协。
Flutter 使用谷歌开发的 Dart 语言进行开发。 Dart 是一种面向对象的语言,同时支持提前编译和即时编译,非常适合用于构建本地应用程序,同时 Flutter 的热加载有效的提高了开发效率。 Flutter 最近也转向了 Dart 2.0 版本。
Dart 提供了许多其他语言中的功能,包括垃圾回收,异步,强类型,泛型以及丰富的标准库。
2、跨平台框架的发展史
1、使用WebApp的一些框架
1、Ruby on Rails
2、AngularJS
3、JQuery Mobile
4、Cordova
5、PWA
6、Instant App
优势:
一套HTML5APP 即可同时适用iOS、Android平台,适配性和体验较好。
版本服务器更新,用户永远看到的是最新APP端的信息。
技术难度较低,开发工作量小,开发成本低。
劣势:
用户体验大幅落后于原生APP,操作的流畅度,程序的执行效率,与原生APP都有较大差距;
HTML5 APP 受网速的影响较大,在网络情况较差的情况下,HTML5 APP 往往连打开都困难,而原生程序,基本都能顺利打开运行(只是速度较慢)。
2、 适合移动端App的一些框架
1、React Native
特点:Facebook 出品的一个移动端开发框架,可以最大限度的接近原生框架,就能够在Javascript和React的基础上获得完全一致的开发体验,构建原生App,仅需学习一次,编写任何平台。(Learn once, write anywhere)
缺点:初次学习成本高,必须不同平台写两套代码,依赖暴露的接口
2、Weex
特点:weex 能够完美兼顾性能与动态性,让移动开发者通过简捷的前端语法写出Native级别的性能体验,并支持iOS、Android、YunOS及web等多端部署。
缺点:控件太少,基本只能实现最基本的效果;上手难度打,如果是前段和移动端都懂的话上手很快;随着项目变大,编译速度会呈指数型上升。
3、Flutter
1、免费开源;
2、利用保持状态的热重载(hot reload)、全新的响应式框架、丰富的控件以及集成的开发工具,这些特点进行快速开发;
3、通过可组合的控件集合、丰富的动画库以及可扩展的框架来实现富有感染力的灵活界面设计;
4、借助可移植的GPU加速的渲染引擎以及高性能本地ARM代码运行时以达到跨设备的高品质用户体验;
5、提高开发效率:使用一套代码同时开发iOS和Android;
6、可扩展性强:Flutter框架本身提供了丰富的Material Design和Cupertino(iOS-flavor)风格的控件,可自由扩展控件,不受手机平台控件的限制。
Flutter框架
Flutter框架是一个分层的结构,每个层都建立在前一层之上。
image.png
Flutter跨平台最核心的部分,是它的高性能渲染引擎(Flutter Engine)。Flutter不使用浏览器技术,也不使用Native的原生控件,它使用自己的渲染引擎来绘制widget。
说到widget,就要说一句Flutter的一切皆为widget理念。widget是Flutter应用程序用户界面的基本构建块。每个widget都是用户界面一部分的不可变声明。与其他将视图、控制器、布局和其他属性分离的框架不同,Flutter具有一致的统一对象模型:widget。在更新widget的时候,框架能够更加的高效。
对于Android平台,Flutter引擎的C/C++代码是由NDK编译,在iOS平台,则是由LLVM编译,两个平台的Dart代码都是AOT编译为本地代码,Flutter应用程序使用本机指令集运行。Flutter正是是通过使用相同的渲染器、框架和一组widget,来同时构建iOS和Android应用,而无需维护两套独立的代码库。
image.png
Flutter将UI组件和渲染器从平台移动到应用程序中,这使得它们可以自定义和可扩展。Flutter唯一要求系统提供的是canvas,以便定制的UI组件可以出现在设备的屏幕上。
Flutter安装 -- #官网链接>>> --**
image.pngimage.png
image.png
image.png
3、开发工具
Flutter 在开发工具的选择上很灵活。 应用程序可以通过命令行以及任何编辑器轻松开发,这些编辑器来自受支持的 IDE,如 VS Code,Android Studio 或 IntelliJ。 使用哪种 IDE 取决于用户的偏好。
Android Studio 提供了最多的功能,例如 Flutter Inspector 来分析正在运行的应用程序的窗口部件以及监视应用程序性能。 还提供了开发部件层次结构时很方便的几个重构。
VS Code 提供了更轻松的开发体验,因此它的启动速度往往比 Android Studio / IntelliJ 更快。 每个 IDE 都提供内置的编辑助手,如代码补全,接口定义跳转以及良好的调试支持。
Flutter 也很好的支持命令行,这使得创建,更新和启动应用程序变得容易,除了编辑器之外没有任何其他工具依赖性。
4、热加载
无论采用何种工具,Flutter 都能为应用程序的热加载提供出色的支持。 这允许在许多情况下修改正在运行的应用程序,维护状态,而不必停止应用程序,重新构建和重新部署。
5、测试
Flutter 包含一个 WidgetTester 实用程序,用于与测试中的部件进行交互。 新的应用程序模板包含一个示例测试,用于演示在创建测试时如何使用它。
6、包管理和插件 pub链接
Flutter 已经有了一个丰富的开发者生态系统:开发人员已有大量可以使用的包和插件。
要添加包或插件,只需在应用程序的根目录下的 pubspec.yaml 文件中包含依赖项即可。 然后从命令行或 IDE 运行 flutter packages get,Flutter 的工具将引入所有必需的依赖关系。
要将流行的图像选择器插件用于 Flutter,只需在 pubspec.yaml 中将其列为依赖项
然后运行 flutter packages get 拉取所有依耐项,然后可以在 Dart 中导入和使用它
image.png
6、部件
Flutter 里的所有东西都是一个一个的部件。 这包括用户界面元素,例如 ListView,TextBox 和 Image,以及框架的其他部分,包括布局,动画,手势识别和主题等。
通过将所有内容都设置为窗口部件,整个应用程序可以在窗口部件层次结构中表示。 拥有一个所有内容都是部件的架构,可以清楚地了解作用于某一部分的属性和行为的来源。 这与大多数其他应用程序框架不同,它们将属性和行为不一致地关联起来,有时将属性和行为从层次结构中的其他组件附加到控件本身,有时自身控制属性和行为。
7、运行第一个Flutter应用
image.pngimage.png
部件示例
Flutter 应用程序的入口点是 main 函数。 要在屏幕上放置用户界面元素的部件,在 main()中调用 runApp()并将部件层次结构根部的部件作为参数传递。
image.png
无状态 VS 有状态
部件有两种形式:无状态和有状态。 无状态部件在创建和初始化后不会更改它们的内容,而有状态部件维护一些程序运行时可变的状态,例如,响应用户交互。
image.png
在实例中无状态的Widget继承自StatelessWidget,其初始化之后,不会更改内部内容。
有状态的Widget继承自StatefulWidge,有状态的部件返回一个负责为给定状态构建部件树的 State 类。 状态更改时,将重建窗口部件树的关联部分。通过setState()方法改变部件状态。状态在传递给 setState()的函数中更新。 当调用 setState()时,该函数可以设置任何内部状态。
布局
默认情况下,runApp 函数会使窗口填充整个屏幕。 为了控制窗口部件布局,Flutter 提供了各种布局窗口部件。 一些布局部件用于子部件的垂直或水平对齐,扩展部件以填充特定空间,将部件限制到特定区域,将它们在屏幕上居中,并允许部件相互重叠。
两个常用的部件是行和列。这些部件执行布局以水平(行)或垂直(列)显示其子部件。
使用这些布局部件只需将它们包装在子部件列表中。mainAxisAlignment 用于控制部件如何沿布局轴线摆放,无论是居中,左对齐,右对齐还是使用各种间距对齐。
以下代码显示如何对齐行或列中的多个子部件:
image.png
响应触摸事件
触摸交互是使用手势处理的,手势被封装在 GestureDetector 类中。由于它也是一个部件,因此添加手势识别只需要将子部件封装在 GestureDetector 部件中。
例如,要向 Icon 添加触摸处理,请将其设置为 GestureDetector 的子项,并设置检测器的回调以捕获所需的手势。
image.png
在这种情况下,当点击图片,双击或长按时,会打印对应输出。
除了简单的点击手势外,还有丰富的识别器,适用于从平移和缩放到拖动的所有内容。 这使得构建交互式应用程序变得非常简单。
绘制
Flutter 还提供了各种部件用于绘制,包括修改不透明度,设置剪切路径和应用装饰。 它甚至通过 CustomPaint 部件以及相关的 CustomPainter 和 Canvas 类支持自定义绘制。
绘制部件的一个示例是 DecorativeBox,它可以将 BoxDecoration 绘制到屏幕上。 以下示例显示如何使用它通过渐变来填充屏幕:
image.png
动画
Flutter 包含一个 AnimationController 类,用于控制动画播放,包括开始和停止动画,以及改变动画的值。 此外,还有一个 AnimatedBuilder 部件,允许与 AnimationController 一起构建动画。
任何部件(例如前面显示的装饰星形)都可以对其属性进行动画处理。 例如,将代码重构为 StatefulWidget,因为动画是状态更改,并且将 AnimationController 传递给 State 类允许在构建部件时使用动画值。
image.png
在这种情况下,该值用于改变窗口部件的大小。 只要动画值发生变化就会调用 build 函数,从而导致星形的大小在 750 毫秒内变化,从而创建一个缩放效果。
Flutter与原生交互
为了在 Android 和 iOS 上提供对本机平台 API 的访问,Flutter 应用程序可以使用平台通道。 这允许 Dart 代码将消息发送到 iOS 或 Android 宿主应用。 许多可用的开源插件都是使用平台通道上的消息传递构建的。
Flutter界面调用包名
定义渠道名设置对应方法名,并监听方法名,获取对应方法返回结果
image.png
image.png
iOS AppDelegate设置监听对象,并实现对应方法
image.png
Android 的MainActivity设置监听对象,并实现对应方法
image.png
Flutter调研
生态
在Flutter官方的Pub平台上,纯Flutter Package大概有两千多个,基本上常见的库还是都有的,例如网络、图片、音视频播放等等。但是对于目前Android以及iOS的生态,还是远远的不足的,对于一些复杂的UI或者一些不是特别通用的功能,就得自己去实现。
包大小
根据官网的介绍,一个最小的Android版本的Flutter应用。release版本大小约6.7MB,其中核心引擎大约3.3MB,框架+应用程序代码大约是1.25MB,LICENSE文件(包含在app.flx中)是55k,必需的Java代码.dex为40k,并且约有2.1MB的ICU数据。考虑到目前网络环境,包大小的增加,还也在可以接受的范围。
Crash
iOS运行官方的例子,会有时候crash掉,因此我们将一个开源的Flutter应用,添加了Bugly上报,在Android平台进行了众测。
image.png参与人次大概150人左右,启动次数大概500次左右,没有出现一次Crash数据上报,由于app很简单,并不能说明很多问题,但是众测用户反馈了约12条信息,其中1条是类似于ANR,无法操作,其余的部分则是卡顿相关的反馈。
流畅性
将官方的例子发给测试同学,让在iOS以及Android平台的不同机子上运行了下。在iOS上基本上流畅运行,没有出现卡顿的现象,在Android部分设备上,出现了卡顿的现象。
image.png
结论
即使在测试版中,Flutter 也为构建跨平台应用程序提供了一个很好的解决方案。凭借其出色的工具和热加载,它带来了非常愉快的开发体验。
个人而言,我觉得可以放心大胆的去学习尝试,独立开发app,可以写一套代码,在多个平台运行发布。
如果单纯从Flutter本身能够解决的问题的方面出发,使用Flutter确实能够产生一定的收益,节省开发成本,如果考虑到目前坑比较多的状况,加上踩坑的时间,可能就无法去评估了。
丰富的开源软件包和出色的文档使得开始使用起来非常容易。展望未来,除了 iOS 和 Android 之外,Flutter 开发人员还可以针对 Fuchsia。 考虑到引擎架构的可扩展性,Flutter 出现在其他平台上并不令人意外。 随着社区日益壮大,现在是一个很好的时机入手。
总体来说,Flutter确实是一个比较不错的东西,如果谷歌能够把它发展的比较完善,对于个人以及小团队来说,确实是个福音。