Flutter介绍

Java 发表评论

1.flutter简介

Flutter是Google使用Dart语言开发的移动应用开发框架,使用一套Dart代码就能快速构建高性能、高保真的iOS和Android应用程序,并且在排版、图标、滚动、点击等方面实现零差异。

快速开发:

毫秒级的热重载,修改后,您的应用界面会立即更新。使用丰富的、完全可定制的widget在几分钟内构建原生界面。

富有表现力和灵活的UI:

快速发布聚焦于原生体验的功能,分层的架构允许您完全自定义,从而实现难以置信的快速渲染和富有表现力、灵活的设计。

原生性能

Flutter包含了许多核心的widget,如滚动、导航、图标和字体等,这些都可以在iOS和Android上达到原生应用一样的性能。

 

Flutter适合谁?(官方说明)

  Flutter适用于希望以更快的方式构建漂亮的移动应用程序的开发人员,或者通过单一研发投入得更多用户的方式(同一份代码支持IOS和Android)。

  Flutter也适用于需要领导移动开发团队的工程经理。 Flutter允许经理创建一个移动应用开发团队(而不是IOS和Android两个团队),统一大家的开发方式以更快地向向iOS和Android发布相同的功能,同时,并降低维护成本。
  虽然不是最初的目标受众,但Flutter也适用于那些希望将其原始设计愿景以高保真度呈现给所有移动用户的设计师。

Flutter可以构建什么类型的应用程序?

  Flutter针对想要在Android和iOS上运行的2D移动应用进行了优化。您可以使用Flutter构建全功能应用程序,包括相机、地理位置、网络、存储、第三方SDK等。

我应该用Flutter制作我的下一个应用程序吗?(官方,版本更新到0.5Beat)

  Flutter仍在开发中,尚未发布1.0。

  flutter API正在稳定,我们将继续根据用户反馈改进系统的某些部分。当我们发布了可能会影响用户的更改,我们会发送电子邮件至flutter-dev@googlegroups.com。

  Flutter在Google内部已经被使用,并且使用Flutter构建的应用程序已经发布了。

  一些关键功能(如辅助功能)尚未准备好广泛部署。

2.跨平台技术演进

现在主流的移动开发平台是Android和iOS,每个平台的开发技术都不太一样,针对每个平台开发应用需要特定人员,这样开发相对一套代码效率低下,需要进行跨平台开发。包括最开始的Hybrid混合开发技术,到RN的桥接技术,到现在新兴的Flutter技术,跨平台开发技术一直在演进。

Hybrid开发,主要依赖于WebView。但是WebView是一个很重的控件,很容易产生内存问题,而且复杂的UI在WebView上显示的性能不好。

react-native技术抛开了WebView,利用JavaScriptCore来做桥接,将js调用转为native调用。react-native最终会生成对应的自定义原生控件,这种策略也将框架本身和App开发者绑在了系统的控件系统上,不仅框架本身需要处理大量平台相关的逻辑,随着系统版本变化和API的变化,开发者可能也需要处理不同平台的差异,甚至有些特性只能在部分平台上实现,这样框架的跨平台特性就会大打折扣。

Flutter实现跨平台采用了更为彻底的方案,自己实现了一台UI框架,然后直接系统更底层渲染系统上画UI。

3.Flutter框架结构

 

Flutter的架构主要分成三层:Framework,Engine和Embedder。

Framework层:

使用dart实现,包括Material Design风格的Widget,Cupertino(针对iOS)风格的Widgets,文本/图片/按钮等基础Widgets,渲染,动画,手势等。

Engine层:

Engine使用C++实现,主要包括:Skia,Dart和Text。

(1)Skia是开源的二维图形库,提供了适用于多种软硬件平台的通用API。

(2)Dart部分主要包括:Dart Runtime,Garbage Collection(GC),如果是Debug模式的话,还包括JIT(Just In Time)支持。Release和Profile模式下,是AOT(Ahead Of Time)编译成了原生的arm代码,并不存在JIT部分。

(3)Text即文本渲染,其渲染层次如下:衍生自minikin的libtxt库(用于字体选择,分隔行),HartBuzz用于字形选择和成型。Skia作为渲染/GPU后端,在Android和Fuchsia上使用FreeType渲染,在iOS上使用CoreGraphics来渲染字体。

Embedder层:

Embedder是一个嵌入层,即把Flutter嵌入到各个平台上去,这里做的主要工作包括渲染Surface设置,线程设置,以及插件等。从这里可以看出,Flutter的平台相关层很低,平台(android,iOS)只是提供一个画布,剩余的所有渲染相关的逻辑都在Flutter内部,这就使得它具有了很好的跨端一致性。

4.跨平台原理

Flutter跨平台最核心的部分,是它的高性能渲染引擎(Flutter Engine)。Flutter不使用浏览器技术,也不使用Native的原生控件,它使用自己的渲染引擎来绘制widget,直接使用Skia引擎来渲染,平台(Android,IOS)只是提供一个画布,剩余的所有渲染相关的逻辑都在Flutter内部,这就使得它具有了很好的跨端一致性。

Dart是用预编译的方式编译多个平台的原生代码,这允许Flutter直接与平台通信,对于Android平台,Flutter引擎的C/C++代码是由NDK编译,在iOS平台,则是由LLVM编译,两个平台的Dart代码都是AOT编译为本地代码,Flutter应用程序使用本机指令集运行。

Flutter正是是通过使用相同的渲染器、框架和一组widget,来同时构建iOS和Android应用,而无需维护两套独立的代码库。

 

Flutter编译的iOS应用程序采取的方案是,使用iOS运行时(Runtime)实现跨平台,iOS运行时(Runtime)是一个用汇编写的一段程序,可以执行C/C++编译的二进制。iOS原生开发的Objective-C语言也是通过iOS运行时(Runtime)执行C/C++的二进制文件,所以Flutter编译的iOS应用能和原生应用不相上下。

Android和iOS系统则是在程序包中内置Flutter Engine虚拟机以运行Flutter应用程序。

Android 平台下说明:

Android Gradle项目中只有一个app module,构建产物即是宿主APK。Flutter在本地运行时默认采用Debug模式,在项目目录执行flutter run即可安装到设备中并自动运行,Debug模式下Flutter使用JIT方式来执行Dart代码,所有的Dart代码都会打包到APK文件中assets目录下,由libflutter.so中提供的DartVM读取并执行。

事实上flutter下的iOS/Android工程本质上依然是一个标准的iOS/Android的工程,flutter只是通过在BuildPhase中添加shell来生成和嵌入App.framework和Flutter.framework(iOS),通过gradle来添加flutter.jar和vm/isolate_snapshot_data/instr(Android)来将Flutter相关代码编译和嵌入原生App而已。因此本文主要讨论因flutter引入的构建,运行等原理。编译target虽然包括arm,x64,x86,arm64,但因原理类似,本文只讨论arm相关(如无特殊说明,android默认为armv7)。

5.Flutter模式

对于Flutter,它支持常见的debug,release,profile等模式。

Debug模式:

对应了Dart的JIT模式,又称检查模式或者慢速模式。支持设备,模拟器(iOS/Android),此模式下打开了断言,包括所有的调试信息,服务扩展和Observatory等调试辅助。此模式为快速开发和运行做了优化,但并未对执行速度,包大小和部署做优化。Debug模式下,编译使用JIT技术,支持广受欢迎的亚秒级有状态的hot reload。

Release模式:

对应了Dart的AOT模式,此模式目标即为部署到终端用户。只支持真机,不包括模拟器。关闭了所有断言,尽可能多地去掉了调试信息,关闭了所有调试工具。为快速启动,快速执行,包大小做了优化。禁止了所有调试辅助手段,服务扩展。

Profile模式:

类似Release模式,只是多了对于Profile模式的服务扩展的支持,支持跟踪,以及最小化使用跟踪信息需要的依赖,例如,observatory可以连接上进程。Profile并不支持模拟器的原因在于,模拟器上的诊断并不代表真实的性能。

6.Flutter插件(库)

Flutter使用的Dart语言无法直接调用Android系统提供的Java接口,这时就需要使用插件来实现中转。

Flutter官方提供了丰富的原生接口封装(大部分插件封装了Android,Ios两端平台相关的功能):

在Flutter中,依赖包由 Pub(https://pub.dartlang.org/packages) 仓库管理,项目依赖配置在pubspec.yaml文件中声明即可,对于未发布在Pub仓库的插件可以使用git仓库地址或文件路径:

在Flutter中,依赖包由 Pub(https://pub.dartlang.org/packages) 仓库管理,项目依赖配置在pubspec.yaml文件中声明即可,对于未发布在Pub仓库的插件可以使用git仓库地址或文件路径。访问pub仓库,大概有3500多个packages,和android,IOS甚至RN规模相差还是比较大的。

7.代码调试

Dart 分析器

  在运行应用程序前,请运行flutter analyze测试你的代码。这个工具将分析你的代码并帮助你发现可能的错误。

Dart Observatory (语句级的单步调试和分析器)

  如果您使用flutter run启动应用程序,那么当它运行时,您可以打开Observatory URL的Web页面, 直接使用语句级单步调试器连接到您的应用程序。如果您使用的是IntelliJ,则还可以使用其内置的调试器来调试您的应用程序。当使用Dart Observatory时,可以使用该debugger()语句插入编程式断点。要使用这个,你必须添加import ‘dart:developer’;到相关文件顶部。

调试模式断言

  在开发过程中,强烈建议您使用Flutter的“调试”模式,有时也称为“checked”模式。 如果您使用flutter run运行程序。在这种模式下,Dart assert语句被启用,并且Flutter框架使用它来执行许多运行时检查来验证是否违反一些不可变的规则。

调试应用程序层

  Flutter框架的每一层都提供了将其当前状态或事件转储(dump)到控制台(使用debugPrint)的功能。 可视化调试   您也可以通过设置debugPaintSizeEnabled为true以可视方式调试布局问题。 当它被启用时,所有的盒子都会得到一个明亮的深青色边框,padding(来自widget如Padding)显示为浅蓝色,子widget周围有一个深蓝色框, 对齐方式(来自widget如Center和Align)显示为黄色箭头. 空白(如没有任何子节点的Container)以灰色显示。

调试动画

  调试动画最简单的方法是减慢它们的速度。为此,请将timeDilation变量(在scheduler库中)设置为大于1.0的数字,例如50.0。 最好在应用程序启动时只设置一次。如果您在运行中更改它,尤其是在动画运行时将其值减小,则框架的观察时可能会倒退,这可能会导致断言并且通常会干扰您的工作。

调试性能问题

  要了解您的应用程序导致重新布局或重新绘制的原因,您可以分别设置debugPrintMarkNeedsLayoutStacks和 debugPrintMarkNeedsPaintStacks标志。 每当渲染盒被要求重新布局和重新绘制时,这些都会将堆栈跟踪记录到控制台。如果这种方法对您有用,您可以使用services库中的debugPrintStack()方法按需打印堆栈痕迹。

Performance Overlay

  要获得应用程序性能图,请将MaterialApp构造函数的showPerformanceOverlay参数设置为true。 这将显示两个图表。第一个是GPU线程花费的时间,最后一个是CPU线程花费的时间。 图中的白线以16ms增量沿纵轴显示; 如果图中超过这三条线之一,那么您的运行频率低于60Hz。横轴代表帧。 该图仅在应用程序绘制时更新,因此如果它处于空闲状态,该图将停止移动。

调试工具使用了前几个,代码分析,界面调试工具用法简单,代码调试工具定位不准确。

 8.优缺点:

优点:

1.支持AOT的Dart语言,AOT方式编译成机器码(ARM),执行效率也比JavaScript高。

2.一套代码运行在多个平台,做到真正的跨平台。

3.JIT & AOT运行模式,支持开发时的快速迭代和正式发布后最大程度发挥硬件性能。Flutter所使用的Dart语言同时支持AOT和JIT运行方式,JIT模式下还有一个备受欢迎的开发利器“热刷新”(Hot Reload),即在Android Studio中编辑Dart代码后,只需要点击保存或者“Hot Reload”按钮,就可以立即更新到正在运行的设备上,不需要重新编译App,甚至不需要重启App,立即就可以看到更新后的样式。

4.Flutter本身支持Android和iOS两个平台,提供了两套设计语言的控件实现Material & Cupertino,可以帮助App更好地在不同平台上提供原生的用户体验,还包含了许多核心的widget,如滚动、导航、图标和字体等,这些都可以在iOS和Android上达到原生应用一样的性能

5.兼容性上,Flutter 提供的 widget 都是基于 skia来实现和精心定制的,与具体平台没关,所以能保持很高的跨 os 跨 os version 的兼容性。

6. Flutter可以复用现有的Java、Swift或ObjC代码,访问iOS和Android上的原生系统功能和系统SDK

7. 通过使用Isolates,可以充分利用多核性能。

8.相较于其他跨平台应用,art语言原生的支持面向对象,函数式编程,响应式编程,泛型,并发。

 

缺点:

1.第三方库较少,许多常用的复杂控件还需要自己实现。

2.调用系统的service仍然需要封装接口,仍然还是需要懂得native开发,简单点说就是需要调用android,IOS的服务,需要写两套android,Ios的代码,然后利用dart调用。

3.Dart 语言很不友好,括号较多,各种嵌套,可读性较差。

4.Flutter官方没有对平板下的运行情况进行测试,有可能一些组件存在issue,目前所有widget都没有对平板进行特殊适配。

5.不支持3d

6.版本不成熟,beat版本还有许多bug,需要到release才能真正用于商业开发。

7.官方提供的组件大部分都以 Material Design 为主,iOS风格的组件比较少,对于需要用到 iOS 风格组件的情况,都需要自己手动绘制组件。

8.社区尚不成熟,开发中遇到问题,不太容易快速找到解决方案,需要踩比较多的坑。

9.Flutter的在调试模式和Release模式下性能差别很大。如果你调试时发现性能差,就最好试试release模式。

 

9.其他

flutter中一切皆为widget:

Widget是Flutter应用程序用户界面的基本构建块。每个Widget都是用户界面一部分的不可变声明。 与其他将视图、控制器、布局和其他属性分离的框架不同,Flutter具有一致的统一对象模型:widget。

动画使用简单:

类似android的动画使用方式,丰富的插值器。

打包的apk体积比较大

因为包括了三个平台的flutterVm,如果只支持armi_v7会小很多,同时发布版本通常远小于调试版本。

Flutter引擎有多大?(官方)

截止2017年6月,我们测量了一个最小的Android版Flutter应用程序(没有Material Components,只是一个Center构建的单个widget的应用)的大小,并将其打包为release版,大小约为6.7MB。
对于这个简单的应用程序,核心引擎大约3.3MB,框架+应用程序代码大约是1.25MB,LICENSE文件(包含在app.flx中)是55k,必需的Java代码.dex为40k,并且约有2.1MB的ICU数据。

可以混合开发吗?

可以在现有的Android或iOS应用中嵌入Flutter

支持webView吗?

支持WebView,试了下还有很多bug。

如何为Flutter编写并行/并发应用程序?

Flutter支持isolates。isolates是Flutter虚拟机中的独立堆,它们可以并行运行(通常作为单独的线程实现)。isolates通过发送和接收异步消息进行通信。

自己写的一些flutter的demo:

https://github.com/hpuzzuldx/flutterDemo

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *