Build beautiful native apps in record time
使用Flutter快速构建,集美观与高性能于一体的移动应用
Flutter的历史
2015年5月 Dart 开发者峰会上,亮相了基于Dart 语言的移动应用程序开发框架Sky [8-9] ,后更名为 Flutter。Dart语言2011年诞生,起初的竞对目标是Js,2016年谷歌的AdWords、AdSense和Fiber项目团队开始把Dart融入他们的前端应用开发。一项当时的内部报告表明,Dart可以帮助他们提升25%到100%的前端开发效率。谷歌内部的Dart代码量比去年增长了3.5倍。
但 Google从前端,到新开发的系统,到我们现在接触到的flutter都是使用dart,足以见得,Google对dart还是一定的重视。
- 2018 年 2 月底在世界移动大会 (MWC) 上宣布了第一个 Beta 版发布;
- 2018 年 5 月的 Google I/O 大会上发布了 Beta 3;
- 2018 年6 月底的 GMTC 宣布了首个发布预览版;
- 2018 年 9 月的谷歌开发者大会 (Google Developer Days) 上,宣布 发布预览版 2 发布。
- 2018 年 12月 Flutter live 2018 发布1.0稳定版本。
- 2019年3月发布1.2,宣布支持Web
- 5月7日 , Google i/O大会 官方宣布,Flutter 1.5 预览版来了,已支持移动、Web、桌面和嵌入式设备,也意味着它正式成为了支持多平台的轻量级 UI 框架,对于开发者而言越来越友好!
一、全球大前端技术大会
1.用户对移动端的依赖度:
2.Flutter的目标:
- 让开发者处于高效状态
- 可以创造出任何设计师期望的界面与效果
- 高效快速的运行速度,不牺牲性能的前提
3.Flutter的特点
- 快速构建,快速调试
- 与原生毫无差异化
- 快速代码测试
- 框架的统一,并提供比原生更丰富的组件
- 更加紧密高效地与GPU连接
- 充分利用硬件的性能
- 最后编译成原生代码
二、Flutter Framework设计
1.声明式+响应式的开发模式
开发者无需过多地关注自己Widget布局的优化,框架本身会去计算哪些Element需要去Build,Layout和Paint。换句话说,框架本身保证了即便应用开发者不做很多优化便可以实现较好的性能。
2.组合性的API
提供了灵活而强大的API。当然对于很多Native背景的开发者而言,这种嵌套式的写法,还是需要时间和成本去习惯的,但绝对不是设计的问题,你会越用越爽。
3.原生的扩展,跨平台的通信
Channel使得开发者可以轻易用于Native的功能扩展,而且是Native体验。
Flutter最大优势,即架构于Skia之上的较彻底的跨平台能力。
贴下Flutter的设计架构:
通过与Skia的深度合作与优化,Flutter可以最大限度地抹平平台差异,提高渲染效率与性能。
4.动画相当丰富且使用方便
Flutter的开发逻辑类似用游戏引擎的方式来写App,用它来开发2D游戏当然也是可行的。
例如:https://github.com/spritewidget/spritewidget
2D动画在线制作:好玩
https://www.2dimensions.com/explore/fork/trending/all
5.Dart语言
虽然Dart在谷歌内部应用很多,但Flutter选择Dart也是有一定的偶然性。
Why Dart? Answer by Hixie From Flutter
从另外的角度看,Dart的很多特点也使得其对于Flutter不可或缺。
a. 支持AOT编译,使得Release模式下可以编译快速,可预测的,Native代码。
b. JIT编译,开发阶段变更迅速生效,hot reload。
c. 对于开发者,容易上手和学习。
Why Flutter Uses Dart
6.其他特性
Hot Reload
Flutter 引入了 Stateful Hot Reload(保持应用状态的热重载),这个新特性可以让移动开发者和设计师们实时迭代应用程序。通过 Stateful Hot Reload,无需重新启动应用就可以在程序运行的时候直接看到代码修改之后的效果,Stateful Hot Reload 改变了开发者们编写应用的方式。据Google 用户反馈,开发者们表示该特性使得开发效率提升了三倍。
像P图一样写代码,实现App开发。
反射的问题
Flutter的反射比较弱,只能用来做一些Introspect和Invoke,目前不具备Objective-C那么强的动态能力。
据我们了解,Flutter禁止反射最重要的原因不是因为包大小,而是为了代码的可预测性。实际上即便打开mirror支持,tree-shaking的逻辑也是work的。
目前我们对于json<->model这种采用的还是代码生成的方式。
热更新的问题
目前的AOT的编译模式下,Android比较容易实现热更新,原理参见:https://mp.weixin.qq.com/s/vlHt8jxbdzBqJZDobpsFVw
至于iOS的实现,最大的问题不是技术上如何实现,而是如何做才能遵守审核规则而不带来审核风险。
稳定性
从我们的经验来看,Flutter在双端的稳定性(Native Crash)在0.01%这样的量级,都是Engine内部C++的崩溃。
混合的场景
**
这个也要看粒度,分几个层面来看: a. 工程的维度 参见闲鱼等团队的混合工程实践,主要是包名修改,目录结构和打包的问题。 b. 页面的维度 这种维度能够比较好地解决常见的已有Native工程的重构,而且混合页面(栈)方案比较成熟。具体可以参见闲鱼的方案。 c. 一个Native嵌入多个Flutter Card 目前没有现成的好用的封装逻辑,多个Flutter实例会带来过度的内存使用等开销,数据的通信与共享也因为Isolate的隔离变得复杂。 d. 一个Flutter页面嵌入多个Native View Flutter在1.0版本中加入了对于此部分的支持,但还是有一些问题,比如Android上的API Level要求20等。
Flutter直接调用C++
原理上可行,因为Dart本身就可以这么做;实际的支持要看场景和需求。
分包的问题
考虑到tree-shaking的设计,目前的多包还是通过源代码的方式集成。
三、Web
△ 来自丹麦的 Reflectly,使用 Flutter 开发的移动和 Web 应用体验几乎完全一致
Hummingbird: Web 里的 Flutter
如上图所示,在移动端中,C++ 引擎在 Flutter 里面通过 dart:ui 这个库被上层的框架调用。Dart:ui 这个库非常底层,它没有 UI 组件的概念,不知道 UI 布局,也不知道动画。它只做一件事情, 就是把上层框架产生的图片对象画到屏幕上。
Flutter for Web 保留了 Flutter 框架的代码来最大化复用移动端和 Web 端的代码。但是为了能在浏览器里面运行 Flutter 程序,Web 端的 Flutter SDK 用 Flutter Web engine 代替了移动端的 C++ Flutter engine。这个 Flutter Web engine 提供了一个 dart:ui 库在 Web 平台上的实现,它做的事和移动端 dart:ui 很相似——把 Flutter 上层框架产生的图片对象 “画” 到网页上。
具体来说,Flutter Web engine 会优先使用 HTML 和 CSS 来绘制图像。这样做可以利用到浏览器自身的性能优化机制,也不用担心缩放页面的时候出现像素化的问题。只有在少数情况下,Flutter Web engine 会用 Canvas 来实现绘图。我们目前也在尝试使用 CSS Paint API 来代替 Canvas 绘图以提高性能。但是这个 API 还比较新,有待各大浏览器提供支持。
试想一下 Flutter 开发iOS 和Android的App 还免费赠送一份Web版,并且比传统的web开发出来的体验还好。Write once ,Run anywhere。美滋滋
Dart语言最早就是抱着取代JavaScript的初衷出现的,只是鉴于js生态(代码库,多平台上的调试与优化等)的庞大和难以替代。Dart最终于2015年放弃了将VM置入Chrome,转而专注于Dart2JS的方式。
四、桌面 Flutter for Desktop
今年1月 ,Flutter 团队表示将支持移动端之外的平台,一直将 Flutter for Desktop 作为实现性项目,现在正在将其应用到 Flutter 引擎,现在还在内部开发阶段,但已发布早期版本的愿景 —— 用于开发在 Mac, Windows 和 Linux 上运行的 Flutter 应用程序。
Flutter for Embedded Devices
嵌入式设备,Flutter 团队最近发布了 Flutter 支持直接在树莓派等小型设备上运行。
新的知识体系+工具链
Flutter设计确实很赞,尽可能地抽取出了最小的平台相关性,将尽可能多的逻辑实现变得平台无关,最大程度上实现了Write One, Run Everywhere。但毕竟有的内容是无法绕开原生系统(Embedder)的,比如说键盘,输入框等,而这些部分在开发过程中也往往是痛点。 此外,Flutter其实是一个系统的内容,知识面和工具链包括但不限于以下部分: a. Dart pub用来管理Dart依赖 Dart Remote Debugger用来调试Dart代码 Observatory可用于同VM通信,实现调试,Profile,内存对象监控等。
b. Flutter 组合式的API,对于Native背景的开发者书写UI还需要学习适应 Flutter Widget Inspector查看View层次。 PerformanceOverlay查看实时渲染帧率等 Flutter开关+Observatory查看CPU渲染性能瓶颈 SkDebugger查看GPU渲染性能瓶颈
c. engine代码获取与构建 gclient管理代码依赖 ninja管理构建 flutter_gdb用于调试Android Engine; lldb用来调试iOS Engine。
总结:
Flutter的核心是一个独立的可执行二进制文件,所以它不仅能改变移动开发的世界,也能改变桌面开发的世界。你只需编写一次代码,就可以在 Android、iOS、Windows、Mac 和 Linux上以原生方式发布,还能通过 AngularDart 与 Web 共享业务逻辑——这一点意义重大
Flutter的开放性
Flutter面向未来
基础架构设计决定了一个软件的发展上限,它带来了更多的想象力。使用Flutter和Dart,既是Google为摆脱和Oracle纠缠多年的“Java 侵权案”提前下的一颗棋,也是Google为下一代操作系统Fusion下的一颗棋,是即Google通过chromium项目渐进的统一浏览器领域,着眼于更多的终端,为了一个更大终端生态的大一统做准备。这让Flutter和Dart充满了更高层次的可能。如果没有这些可能,Flutter的生命无疑是会短暂的,因为它还未能建立被广泛被认可的标准,就像我们终端里走过的那么多的技术一样,都是有限的解决了当下的诉求,但随着终端的更替,操作系统的演进,慢慢变成了明日黄花。而正是这些更多的可能,是Flutter持续演进的源泉,是Flutter相比其他的跨平台方案中最吸引人的部分
官方在年初表示2019年度的重点关注:
- 核心和基础
- 易用性
- 生态系统
- 支持移动端之外的平台
- 动态更新
- 工具链
Flutter 团队表示,按计划会根据大家的反馈以及新的市场变化来做调整,Flutter 的产品经理 Tim Sneath “这份计划的内容我们不尽然一定会完成的工作。Flutter 是一个开源项目,我们欢迎大家参与到我们开源当中来”