一.什么是flutter?
Flutter是Google发布的一个用于创建跨平台、高性能移动应用的框架。Flutter没有使用原生控件,相反都实现了一个自绘引擎,使用自身的布局、绘制系统。
2017 年 Google I/O 大会上,Google 首次推出了一款新的用于创建跨平台、高性能的移动应用框架——Flutter。
2018年2月,Flutter发布了第一个Beta版本,同年五月, 在2018年Google I/O 大会上,Flutter 更新到了 beta 3 版本。
2018年6月,Flutter发布了首个预览版本,这意味着 Flutter 进入了正式版(1.0)发布前的最后阶段。
业界发展近况
二.移动开发技术简介
- 原生开发
原生应用程序是指某一个移动平台(比如iOS或安卓)所特有的应用,使用相应平台支持的开发工具和语言,并直接调用系统提供的SDK API。比如Android原生应用就是指使用Java或Kotlin语言直接调用Android SDK开发的应用程序;而iOS原生应用就是指通过Objective-C或Swift语言直接调用iOS SDK开发的应用程序。原生开发有以下主要优势:
可访问平台全部功能(GPS、摄像头,地图等等);
速度快、性能高、可以实现复杂动画及绘制,整体用户体验好;
主要缺点:
平台特定,开发成本高;不同平台必须维护不同代码,人力成本随之变大;
内容固定,动态化弱,大多数情况下,有新功能更新时只能发版;
三. 跨平台技术简介
针对原生开发面临问题,人们一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架(根据其原理,主要分为三类):
- H5 (web技术)
- JavaScript开发+原生渲染 (React Native、Weex)
- 自绘UI+原生(Flutter)
1.H5 (web技术)
通过原生的webview网页加载控件加载h5。
优点: 可以动态化更新
缺点: 加载慢,滚动和动画不流畅,苹果审核难
2.JavaScript开发+原生渲染
React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,
使用Javascript语言,类似于HTML的JSX,以及CSS,flexbox布局来开发移动应用,
优点:性能比webview要快,可以直接使用css样式,flexbox布局,h5很容易上手
缺点:
1.渲染时需要JavaScript和原生之间通信,在有些场景可能会因为通信频繁导致卡顿。
2.javascript为脚本语言,执行时需要jit,执行效率没有aot快
3.渲染依赖原生控件,不同的平台控件需要单独维护,当原生系统更新时,社区控件可能会滞后
4. 兼容性差,升级rn的版本容易导致出错,依赖环境太多,查错麻烦
3.自绘UI+原生(Flutter)
Flutter与用于构建移动应用程序的其它大多数框架不同,因为Flutter既不使用WebView,也不使用操作系统的原生控件。 相反,Flutter使用自己的高性能渲染引擎来绘制widget。这样不仅可以保证在Android和iOS上UI的一致性,而且也可以避免对原生控件依赖而带来的限制及高昂的维护成本。
Flutter使用Skia作为其2D渲染引擎,Skia是Google的一个2D图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现,Skia是跨平台的,并提供了非常友好的API,目前Google Chrome浏览器和Android均采用Skia作为其绘图引擎。
优点:
1.性能块
2. 有2种风格的组件(系统组件库 系统组件库2)
3. 组件很丰富,开发效率很快
缺点:
1.包有点大
2.有些功能过于麻烦,比如数据共享
数据分析
iOS
iPhone 5c 9.0.1
iPhone 6s 10.3.2
测试结论
1、Flutter在低端和中端的iOS机型上,FPS的表现都优于RN 2、CPU的使用上Flutter在低端机上表现略差于RN,中端机型略优于RN 3、值得注意的是内存上的表现(上图红色箭头区域),Flutter在低端机型上的起始内存和RN几乎一致,在中端机型上会多30M左右的内存(分析为Dart VM的内存),可以想到这应该是Flutter针对低端和中端机型上内存策略是不一样的,可用内存少的机型,Dart VM的初始内存少,运行时进行分配(这样也可以理解为什么在低端机上带来了更多的CPU损耗),中端机器上预分配了更多的VM内存,这样在处理时会更加的游刃有余,减少CPU的介入,带来更流畅的体验. 可以看出,Flutter团队在针对不同机型上处理更加的细腻,目的就是为了带来稳定流畅的体验。
Android
Xiaomi 2s 5.0.2
Sumsung S8 7.0
测试结论
1、Flutter在高低端机的CPU上的表现都优于RN,尤其在低端的小米2s上有着更优的表现 2、Android端在原来FPS基础上增加了流畅度的指标,FPS和流畅度的表现Flutter优于RN(计算规则见附参考文章) 3、Android端的内存也是值得关注的一点,在小米2s上起始内存Flutter明显比RN多40M,RN在测试过程中内存飞涨,Flutter相比之下会更稳定,内存上RN侧的代码是需要调优的,同一套代码Flutter在Android和iOS上并没有很大的差异,但是RN的却要在单端调优,Flutter在这项比拼上又更胜一筹。 比较奇怪的是三星S8上Flutter和RN的初始内存是一致的,猜测是RN也Android高端机型上也会预分配一些内存,具体细节还需要更进一步的研究。
flutter特性
1.高性能
flutter的高性能主要由2点来保证
- 采用dart语言开发,dart在jit编译的时候和javascript差不多,但是dart支持aot,在aot的时候性能远远超过js
- flutter使用自己的渲染引擎来渲染ui,布局数据由dart来完成,不像rn那样还要和原生进行交互转换
2.使用Dart开发
开发阶段使用jit, 这样就避免了每次改动都要进行编译,极大的节省了开发时间
发布时用aot,直接生成高效的arm代码
3.快速内存分配
Flutter框架使用函数式流,这使得它在很大程度上依赖于底层的内存分配器。因此,拥有一个能够有效地处理琐碎任务的内存分配器将显得十分重要,在缺乏此功能的语言中,Flutter将无法有效地工作。当然Chrome V8的JavaScript引擎在内存分配上也已经做的很好,事实上Dart开发团队的很多成员都是来自Chrome团队的,所以在内存分配上Dart并不能作为超越JavaScript的优势,而对于Flutter来说,它需要这样的特性,而Dart也正好满足而已。
4.类型安全
由于Dart是类型安全的语言,支持静态类型检测,所以可以在编译前发现一些类型的错误,并排除潜在问题
5. 单线程
Dart避免了抢占式调度和共享内存,可以在没有锁的情况下进行对象 分配和垃圾回收,在性能方面表现相当不错。
看看dart
dart基础
flutter架构图
Flutter Framework
这是一个纯 Dart实现的 SDK,它实现了一套基础库,自底向上,我们来简单介绍一下:
底下两层(Foundation和Animation、Painting、Gestures)在Google的一些视频中被合并为一个dart UI层,对应的是Flutter中的dart:ui包,它是Flutter引擎暴露的底层UI库,提供动画、手势及绘制能力。
Rendering层,这一层是一个抽象的布局层,它依赖于dart UI层,Rendering层会构建一个UI树,当UI树有变化时,会计算出有变化的部分,然后更新UI树,最终将UI树绘制到屏幕上,这个过程类似于React中的虚拟DOM。Rendering层可以说是Flutter UI框架最核心的部分,它除了确定每个UI元素的位置、大小之外还要进行坐标变换、绘制(调用底层dart:ui)。
Widgets层是Flutter提供的的一套基础组件库,在基础组件库之上,Flutter还提供了 Material 和Cupertino两种视觉风格的组件库。而我们Flutter开发的大多数场景,只是和这两层打交道。
Flutter Engine
这是一个纯 C++实现的 SDK,其中包括了 Skia引擎、Dart运行时、文字排版引擎等。在代码调用 dart:ui库时,调用最终会走到Engine层,然后实现真正的绘制逻辑。
环境搭建
- 获取Flutter SDK
https://github.com/flutter/flutter/releases 配置
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn - 安装开发工具
安装Android Studio
安装Xcode - 安装Flutter和Dart插件
Flutter插件: 支持Flutter开发工作流 (运行、调试、热重载等)。
Dart插件: 提供代码分析 (输入代码时进行验证、代码补全等)。
代码结构
flutter知识体系
组件
主要有2种类型的组件,StatelessWidget和StatefulWidget
- StatefulWidget:表示不需要更新的组件
- StatelessWidget:可以通过setstate来更新组件
响应式编程
React中提出一个重要思想:状态改变则UI随之自动改变,而React框架本身就是响应用户状态改变的事件而执行重新构建用户界面的工作,这就是典型的响应式编程范式
线性布局(Row和Column)
所谓线性布局,即指沿水平或垂直方向排布子组件
弹性布局(Flex)
弹性布局允许子组件按照一定比例来分配父容器空间
流式布局 (Wrap)
类似于九宫格布局,可以设置元素直接的间隔,行的间隔,方向,起始位置等等
层叠布局 Stack、Positioned
层叠布局和Web中的绝对定位、Android中的Frame布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。绝对定位允许子组件堆叠起来(按照代码中声明的顺序)
对齐与相对定位(Align)
组件可以调整子组件的位置,9个方向
普通路由
路由表-命名路由
文件共享
数据库
eventbus
InheritedWidget
是Flutter中非常重要的一个功能型组件,它提供了一种数据在widget树中从上到下传递、共享的方式,比如我们在应用的根widget中通过InheritedWidget共享了一个数据,那么我们便可以在任意子widget中来获取该共享的数据
定义
存
取
通过按钮
通过手势:点击、双击、长按、拖动、滑动、缩放
Future对象表示异步操作的结果,我们通常通过then()来处理返回的结果
async用于标明函数是一个异步函数,其返回值类型是Future类型
await用来等待耗时操作的返回结果,这个操作会阻塞到后面的代码
app生命周期
需要,因为一些系统功能都需要通过原生来开发,比如拍照,相册,蓝牙,地图,推送,音视频,聊天
一些解决原生错误的能力
可以的