Flutter介绍

跨平台技术简介

针对原生开发面临问题,人们一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架,根据其原理,主要分为三类:

基于WebView(Cordova、AppCan)

这类框架主要原理就是利用Android和 iOS 上的 webview 容器,APP 能够执行 html、css 和 js 脚本,展示 web 页面。如果需要原生功能就添加 bridge 供 javascript 调用。具有开发效率高、跨平台、支持动态发布等特点,它是目前应用最广泛最成熟的一种方案。基于WebView的框架优点很明显,它们几乎可以完全继承现代Web开发的所有成果(丰富得多的控件库、满足各种需求的页面框架、完全的动态化、自动化测试工具等等),当然也包括Web开发人员,不需要太多的学习和迁移成本就可以开发一个App。同时WebView框架也有一个致命(在对体验&性能有较高要求的情况下)的缺点,那就是WebView的渲染效率和JavaScript执行性能太差。再加上Android各个系统版本和设备厂商的定制,很难保证在所有设备上都能提供一致的体验。

原生渲染 (React Native、Weex)

为了解决WebView性能差的问题,以React Native为代表的一类框架将最终渲染工作交还给了系统,虽然同样使用类HTML+JS的UI构建逻辑,但是最终会生成对应的自定义原生控件,以充分利用原生控件相对于WebView的较高的绘制效率。与此同时这种策略也将框架本身和App开发者绑在了系统的控件系统上,不仅框架本身需要处理大量平台相关的逻辑,随着系统版本变化和API的变化,开发者可能也需要处理不同平台的差异,甚至有些特性只能在部分平台上实现,这样框架的跨平台特性就会大打折扣。由于渲染依赖原生控件,不同平台的控件需要单独维护,其控件系统也会受到原生UI系统限制;执行时需要JIT,执行效率和AOT代码仍有差距,复杂页面和场景会导致卡顿。

Flutter

Flutter则开辟了一种全新的思路,从头到尾重写一套跨平台的UI框架,包括UI控件、渲染逻辑甚至开发语言。渲染引擎依靠跨平台的Skia图形库来实现,依赖系统的只有图形绘制相关的接口,可以在最大程度上保证不同平台、不同设备的体验一致性,同时也拥有媲美原生的高性能体验。逻辑处理使用支持AOT的Dart语言,执行效率也比JavaScript高得多。自绘引擎解决的是UI的跨平台问题,如果涉及其它系统能力调用,依然要涉及原生开发。

Flutter高性能主要靠两点来保证,首先,Flutter APP采用Dart语言开发。Dart在 JIT(即时编译)模式下,速度与 JavaScript基本持平。但是 Dart支持 AOT,当以 AOT模式运行时,JavaScript便远远追不上了。速度的提升对高帧率下的视图数据计算很有帮助。其次,Flutter使用自己的渲染引擎来绘制UI,布局数据等由Dart语言直接控制,所以在布局过程中不需要像RN那样要在JavaScript和Native之间通信,这在一些滑动和拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以JavaScript需要和Native之间不停的同步布局信息,这和在浏览器中要JavaScript频繁操作DOM所带来的问题是相同的,都会带来比较可观的性能开销。

Flutter的开发语言

Dart是一种强类型、跨平台的客户端开发语言。具有专门为客户端优化、高生产力、快速高效、可移植(兼容ARM/x86)、易学的OO编程风格和原生支持响应式编程(Stream & Future)等优秀特性。Dart主要由Google负责开发和维护。

Dart本身提供了三种运行方式:

  1. 使用Dart2js编译成JavaScript代码,运行在常规浏览器中(Dart Web)。
  2. 使用DartVM直接在命令行中运行Dart代码(DartVM)。
  3. AOT方式编译成机器码,例如Flutter App框架(Flutter)。

Flutter最终选择Dart作为开发语言主要有几个原因:

  1. 健全的类型系统,同时支持静态类型检查和运行时类型检查。
  2. 代码体积优化(Tree Shaking),编译时只保留运行时需要调用的代码(不允许反射这样的隐式引用),所以庞大的Widgets库不会造成发布体积过大。
  3. 丰富的底层库,Dart自身提供了非常多的库。
  4. 多生代无锁垃圾回收器,专门为UI框架中常见的大量Widgets对象创建和销毁优化。
  5. JIT & AOT运行模式,支持开发时的快速迭代和正式发布后最大程度发挥硬件性能 

JIT和AOT:

目前,程序主要有两种运行方式:静态编译与动态解释。静态编译的程序在执行前全部被翻译为机器码,通常将这种类型称为AOT (Ahead of time)即 “提前编译”;而解释执行的则是一句一句边翻译边运行,通常将这种类型称为JIT(Just-in-time)即“即时编译”。AOT程序的典型代表是用C/C++开发的应用,它们必须在执行前编译成机器码,而JIT的代表则非常多,如JavaScript、python等,事实上,所有脚本语言都支持JIT模式。但需要注意的是JIT和AOT指的是程序运行方式,和编程语言并非强关联的,有些语言既可以以JIT方式运行也可以以AOT方式运行,如Java、Python,它们可以在第一次执行时编译成中间字节码、然后在之后执行时可以直接执行字节码。

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

Flutter的自绘引擎

Flutter与用于构建移动应用程序的其它大多数框架不同,因为Flutter既不使用WebView,也不使用操作系统的原生控件。 相反,Flutter使用自己的高性能渲染引擎来绘制widget。这样不仅可以保证在Android和iOS上UI的一致性,而且也可以避免对原生控件依赖而带来的限制及高昂的维护成本。

Flutter使用Skia作为其2D渲染引擎,Skia是Google的一个2D图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现,Skia是跨平台的,并提供了非常友好的API,目前Google Chrome浏览器和Android均采用Skia作为其绘图引擎。

目前Flutter默认支持iOS、Android、Fuchsia(Google新的自研操作系统)三个移动平台。Flutter亦可支持Web开发和PC开发。

Flutter框架结构

图1-1

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层,然后实现真正的绘制逻辑。

所有功能都可以通过组合多个Widget来实现,包括对齐方式、按行排列、按列排列、网格排列甚至事件处理等等。Flutter控件主要分为两大类,StatelessWidget和StatefulWidget,StatelessWidget用来展示静态的文本或者图片,如果控件需要根据外部数据或者用户操作来改变的话,就需要使用StatefulWidget。

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          child: new Text('Hello World'),
        ),
      ),
    );
  }
}

Flutter的使用与集成

使用 Flutter 从头开始写一个 App,是一件轻松惬意的事情。但对于成熟产品来说,完全摒弃原有 App 的历史沉淀,而全面转向 Flutter 并不现实。用 Flutter 去统一 iOS/Android 技术栈,把它作为已有原生 App 的扩展能力,通过逐步试验有序推进从而提升终端开发效率,可能才是现阶段 Flutter 最具吸引力的地方。

那么,Flutter 工程与原生工程该如何组织管理?不同平台的 Flutter 工程打包构建产物该如何抽取封装?封装后的产物该如何引入原生工程?原生工程又该如何使用封装后的 Flutter 能力?

Flutter 集成方式主要有以下两种:

  • 将原生工程作为 Flutter 工程的子工程,由 Flutter 统一管理。这种模式,就是统一管理模式
  • 将 Flutter 工程作为原生工程共用的子模块,维持原有的原生工程管理方式不变。这种模式,就是三端分离模式

 

使用统一管理模式,随着功能迭代的深入,工程不断增长扩大,这种方案的弊端也随之显露,不仅三端(Android、iOS、Flutter)代码耦合严重,相关工具链耗时也随之大幅增长,导致开发效率降低。

所以按照三端代码分离的模式来集成会更合适一些,三端代码分离模式把 Flutter 模块作为原生工程的子模块,实现了 Flutter 工程的轻量级接入,还可以快速实现 Flutter 功能的“热插拔”,降低原生工程的改造成本。三端工程分离模式的关键是将Flutter作为一个模块来开发,最终编译成依赖包,即 Android 使用 aar、iOS 使用 pod。换句话说,这样原生工程就可以像引用其他第三方原生组件库那样快速接入 Flutter 了。


Flutter与原生的交互

我们知道一个完整的Flutter应用程序实际上包括原生代码和Flutter代码两部分。由于Flutter本身只是一个UI系统,它本身是无法提供一些系统能力,比如使用蓝牙、相机、GPS等,因此要在Flutter APP中调用这些能力就必须和原生平台进行通信。为此,Flutter中提供了一个平台通道(platform channel),用于Flutter和原生平台的通信。平台通道正是Flutter和原生之间通信的桥梁,它也是Flutter插件的底层基础设施。

Flutter使用了一个灵活的系统,允许您调用特定平台的API,无论在Android上的Java或Kotlin代码中,还是iOS上的ObjectiveC或Swift代码中均可用。

Flutter与原生之间的通信依赖灵活的消息传递方式:

  • 应用的Flutter部分通过平台通道(platform channel)将消息发送到其应用程序的所在的宿主(iOS或Android)应用(原生应用)。
  • 宿主监听平台通道,并接收该消息。然后它会调用该平台的API,并将响应发送回客户端,即应用程序的Flutter部分。

平台通道

使用平台通道在Flutter(client)和原生(host)之间传递消息,如下图所示:

平台通道

当在Flutter中调用原生方法时,调用信息通过平台通道传递到原生,原生收到调用信息后方可执行指定的操作,如需返回数据,则原生会将数据再通过平台通道传递给Flutter。值得注意的是消息传递是异步的,这确保了用户界面在消息传递时不会被挂起。

Flutter的优势

综上所述,总结来说,Flutter的优势有如下几个方面

性能强大,流畅
Flutterreact native相比,性能的强大是有目共睹的。基于dom树渲染原生组件,很难与直接在原生视图上绘图比肩性能,这个优势在滑动和播放动画时尤为明显。

优秀的动画设计
Flutter的动画简单到不可思议,动画对象会根据屏幕刷新率每秒产生很多个(一般是60个)浮点数,只需要将一个组件属性通过补间(Tween)关联到动画对象上,Flutter会确保在每一帧渲染正确的组件,从而形成连贯的动画。这种十分暴力的操作在Flutter上却看不到明显的卡顿,这也是Flutter的一个魔力所在。相比之下其他跨平台框架几乎不能设计动画……往往会遭遇非常严重的性能问题。

UI跨平台稳定
Google直接在两个平台上在底层重写了UIKit,不依赖于Css等外部解释器,几乎不存在UI表达不理想,渲染不正常的情况,可以获得非常稳定的UI表达效果。Css换个浏览器就有不同的表现,基于Css的跨平台框架很难获得稳定的UI表现。

语言特性优秀
Dart是一个静态语言,这也是相对于js的一个优势。静态语言可以避免错误,获得更多的编辑器提示词,极大的增加可维护性。

Flutter缺点

不支持热更新,

Widget繁多,难以选择

架构和管理模式还不够成熟

兼容适配问题多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值