01-📝Flutter核心知识|了解Flutter开发【诞生背景、应用简介、页面渲染原理、搭建开发环境、创建Flutter项目的几种方式】

2,004 阅读19分钟

一、前言

本系列文章旨在快速复习并上手Flutter开发,并在适当分享在项目实战过程中遇到的一些比较有价值的知识内容:

本系列文章内容篇幅如下:

  • 一、了解Flutter开发
      1. Flutter的特性与应用场景
      1. Flutter绘制原理
      1. 与Flutter相关的技术原理
      1. 搭建Flutter开发环境
      1. 创建Flutter项目的几种方式
  • 二、快速入门Flutter开发知识大纲
      1. Dart语言快速入门
      1. Flutter的Widget
  • 三、常见应用功能模块与开源项目
      1. 常见应用功能模块
      1. 不错的开源项目

1. 移动开发的几种方式

移动开发的几种方式

  • 原生开发
  • 跨平台开发

原生开发

  • 原生应用程序是指某一个移动平台(比如iOS安卓)所特有的应用
  • 使用相应平台支持的开发工具语言,并直接调用系统提供的SDK API:
    • 比如Android原生应用就是指使用JavaKotlin语言直接调用Android SDK开发的应用程序;
    • iOS原生应用就是指通过Objective-CSwift语言直接调用iOS SDK开发的应用程序。
  • 移动互联网发展初期
    • 在移动互联网发展初期,业务场景并不复杂
    • 原生开发还可以应对产品需求迭代。
  • 近几年
    • 但近几年,随着物联网时代到来、移动互联网 高歌猛进日新月异:
    • 在很多业务场景中,传统的纯原生开发已经不能满足日益增长的业务需求
    • 主要表现在:
      • 开发效率:JIT编译、动态化热重载
      • 开发成本
      • 多端统一性: 用户界面」、热更新
    • 动态化内容需求增大
      • 当需求发生变化时,纯原生应用需要通过版本升级来更新内容
      • 但应用上架、审核是需要周期
        • 这对高速变化的互联网时代来说是很难接受
      • 所以,对应用动态化(不发版也可以更新应用内容)的需求就变的迫在眉睫。
    • 业务需求变化快,开发成本变大
      • 由于原生开发一般都要维护AndroidiOS两个开发团队
      • 版本迭代时,无论人力成本,还是测试成本都会变大。

总结一下,纯原生开发主要面临动态化开发成本两个问题,而针对这两个问题,诞生了一些跨平台的动态化框架。

  • 主要优势:
    • 访问平台全部功能(GPS、摄像头);
    • 速度快性能高、可以实现复杂动画及绘制,整体用户体验好;
  • 主要缺点:
    • 平台特定,开发成本高不同平台必须维护不同代码,人力成本随之变大;
    • 内容固定,动态化弱,大多数情况下,有新功能更新时只能发版;

跨平台技术简介

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

  • WebView技术
  • 类RN技术
  • Flutter技术

2. 快速了解Hybrid技术的特点

几种跨平台方案特点 和 不同方案的性能比较

关于大前端技术的几种跨平台方案特点 和 不同方案的性能比较,若你想深入了解的同学可以参考的这几篇文章:

若你想直接看结论,可以直接跳到小结部分

小结

  1. 渲染性能比较1: WebView < 类ReactNative < 原生。 (因为json的复杂度比html+css低)
  2. 渲染性能比较2: Flutter ≈ Native
  3. 渲染性能比较汇总: 原生渲染 ≈ Flutter渲染 > 类RN大前端 > Web
  • Flutter的优势在于:
    • 跨平台
      • 可以同时运行在 iOSAndroid 两个平台。
    • 热重载(Hot Reload
      • 省去了重新编译代码的时间,极大的提高了开发效率。
    • 同时Flutter又支持跨平台开发,那么其他领域的技术栈存在的价值会越来越低。
    • 以及未来谷歌新系统 “Fuchsia” 的发布与加持。如果谷歌未来的新系统 Fuchsia 能应用到移动端,并且领域替代 Android 。
    • 由于Fuchsia的上层是Flutter编写的,因此Flutter开发成为了移动端领域的必选项

3.Flutter的诞生

每一个技术的诞生都是为了解决一些现有的问题
我们回顾一下,在前面提及了,为了解决原生开发的一些痛点(如开发成本动态化等),至今为止,先后出现了不少跨平台技术方案;

  • 根据其原理,大概出现过三种:
    • ①、WebApp
    • ②、类RN技术
    • ③、Flutter技术
  • Flutter技术的出现解决了
    • 开发效率:
      • 支持JIT即时编译,写完即时渲染;
      • 编写一份代码,编译后多端运行
    • 渲染
      • 效率
        • 不存在 JavaScriptCore VM的解释器过程
      • 结果|多端一致性:
        • 自带渲染框架Skia,不同渠道的渲染结果 相近
    • ......

二、Flutter概述

1. Flutter的特性与应用场景

1.1 Flutter是什么?

对上面的话进行总结:

  • FlutterGoogle 推出并开源的 移动应用UI开发框架,主打跨平台高保真高性能
  • 开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOSAndroid平台
  • Flutter 提供了丰富的组件接口,开发者可以很快地为 Flutter 添加 Native 扩展
  • Flutter是一个UI SDK(Software Development Kit)
  • 可以进行移动端(iOSAndroid),Web端(Beta),桌面(technical preview),跨平台解决方案
  • 移动端目前已经很多公司在用,Google、阿里、腾讯
  • 特别是阿里的闲鱼团队,为Flutter做了非常多的贡献
  • Flutter它是有一统大前端的野心的,并且它正在侵蚀iOSAndroid这些原生开发

1.2.Flutter开发

1.3.Flutter的特点

Google公司在国内做过很多宣讲,其中多次提到Flutter的几个特点:美观快速高效跨平台开放;

1.) 美观:

  • 使用Flutter内置美丽的Material DesignCupertino widget(什么是widget,不着急)
  • 丰富的motion API
  • 平滑而自然的滑动效果和平台感知,为您的用户带来全新体验

2.) 快速&&高效:

  • 快速:
    • Flutter 的 UI 渲染性能很好
    • 在生产环境下,Flutter 将代码编译成机器码执行
    • 并充分利用 GPU 的图形加速能力,因此使用Flutter 开发的移动应用即使在低配手机上也能实现每秒 60 帧的 UI 渲染速度。
    • Flutter 引擎使用 C++ 编写
      • 包括高效的 Skia 2D 渲染引擎
      • Dart 运行时和文本渲染库
  • 高效:
    • 基于 JIT 的快速开发周期:Flutter 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;
      • Hot Reload (热重载),在前端已经不是什么新鲜的东西,但在移动端之前一直是没有的
    • 基于 AOT 的发布包: Flutter 在发布时可以通过 AOT 生成高效的机器码以保证应用性能。而 JavaScript 则不具有这个能力

3.) 跨平台自绘引擎

  • Flutter 与用于构建移动应用程序的其它大多数框架不同
    • Flutter不使用 WebView
    • 不使用操作系统的原生控件
  • 相反,Flutter 使用自己的高性能渲染引擎来绘制 Widget(组件)
    • 这样不仅可以保证在 AndroidiOSUI 的一致性
    • 也可以避免对原生控件依赖而带来的限制及高昂的维护成本
  • Flutter 底层使用 Skia 作为其 2D 渲染引擎
  • Skia 是 Google的一个 2D 图形处理函数库
    • 包含字型坐标转换,以及点阵图,它们都有高效能且简洁的表现
  • Skia 是跨平台的,并提供了非常友好的 API,目前 Google Chrome浏览器和 Android 均采用 Skia 作为其 2D 绘图引擎
  • 目前 Flutter 已经支持 iOSAndroidWebWindowsmacOSLinuxFuchsia(Google新的自研操作系统)等众多平台

4.) 高性能

  • Flutter 旨在提供流畅、高保真的的 UI 体验。为了实现这一点,Flutter 中需要能够在每个动画帧中运行大量的代码
  • 这意味着需要一种既能提供高性能的语言,而不会出现会丢帧的周期性暂停,而 Dart 支持 AOT,在这一点上可以做的比 JavaScript 更好
  • Flutter 使用自己的渲染引擎来绘制 UI ,布局数据等由 Dart 语言直接控制
    • 所以Flutter在布局过程中 不需要像 RN 那样要在 JavaScript 和 Native之间通信
    • 这在一些滑动拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以 JavaScript 需要和 Native 之间不停的同步布局信息
    • 这和在浏览器中JavaScript 频繁操作 DOM 所带来的问题是类似的,都会导致比较可观的性能开销

5.) 开放:

  • Flutter 是开放的,它是一个完全开源的项目

6.) 快速内存分配:

  • Flutter 框架使用函数式流,这使得它在很大程度上依赖于底层的内存分配器
  • 因此,拥有一个能够有效地处理琐碎任务的内存分配器将显得十分重要,在缺乏此功能的语言中,Flutter 将无法有效地工作
  • 当然 Chrome V8JavaScript引擎在内存分配上也已经做的很好
    • 事实上 Dart 开发团队的很多成员都是来自Chrome团队的
    • 所以在内存分配上 Dart 并不能作为超越 JavaScript 的优势,而对于Flutter来说,它需要这样的特性,而 Dart 也正好满足而已。

7.) 采用Dart语言开发:

Flutter 为什么选择了 Dart 而不是 JavaScript
我们先来了解一下之前提到过的两个概念:JITAOT

  • 程序主要有两种运行方式:静态编译动态解释
  • 静态编译的程序在执行前程序会被提前编译为机器码(或中间字节码),通常将这种类型称为AOT (Ahead of time)即 “提前编译
  • 而解释执行则是在运行时将源码实时翻译为机器码来执行,通常将这种类型称为JIT(Just-in-time)即“即时编译
  • 同学们若是想了解一下 编译相关的知识,可以参考我的这篇文章:计算机编译原理-概述
  • 类型安全和空安全
    • 由于 Dart 是类型安全的语言
      • 且 2.12 版本后也支持了空安全特性,所以 Dart 支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题
      • 这一点对于前端开发者来说可能会更具有吸引力
    • 与之不同的,JavaScript 是一个弱类型语言
      • 也因此前端社区出现了很多给 JavaScript 代码添加静态类型检测的扩展语言和工具,如:
      • 微软的 TypeScript 以及Facebook 的 Flow
      • 相比之下,Dart 本身就支持静态类型,这是它的一个重要优势
  • Dart 团队就在你身边-闲鱼
    • 看似不起眼,实则举足轻重
    • 由于有 Dart 团队的积极投入,Flutter 团队可以获得更多、更方便的支持
    • 正如 Flutter 官网所述我们正与 Dart 社区进行密切合作,以改进 DartFlutter 中的使用
    • 例如
      • 当我们最初采用 Dart 时,该语言并没有提供生成原生二进制文件的工具链(这对于实现可预测的高性能具有很大的帮助),但是现在它实现了
      • 因为 Dart 团队专门为 Flutter 构建了它
      • 同样,Dart VM 之前已经针对吞吐量进行了优化,但团队现在正在优化 VM 的延迟时间,这对于 Flutter 的工作负载更为重要

2. Flutter绘制原理

快速了解Flutter的绘制原理

  • 图像是如何显示的? image.png
  • 为什么看到的不是一幅幅图像?
  • 帧率和刷新率的关系
  • 双重缓存(Double Buffer)
  • 双重缓存存在的问题
  • 了解三重缓存(Triple Buffer)
  • Flutter绘制原理图 image.png
  • 渲染引擎skia

如果你感兴趣,想更深入了解Flutter的绘制原理,可以参考我的这篇文章: Flutter页面渲染原理

三、了解移动大前端的其它技术方案页面渲染原理

1. 计算机图形渲染原理

2. iOS图层渲染原理

3. Web技术相关专题

4. Android图层渲染原理

四、搭建Flutter开发环境

1. 操作系统选择

2. 在 macOS上搭建 Flutter 开发环境

  • 注意:随着 Flutter 的升级可能会发生变化,如果下面介绍的内容在您安装 Flutter 时已失效,请访问 Flutter 官网,按照官网最新的安装教程安装
  • 由于 Flutter 会同时构建 AndroidiOS 两个平台的发布包,所以Flutter同时依赖 Android SDKiOS SDK,在安装Flutter也需要安装相应平台的构建工具和SDK

1.) 安装Flutter SDK

    1. Fluttr官网下载其最新可用的安装包,官网地址:docs.flutter.dev/development…
  • 2.解压安装包到我们自己想安装的目录,如:
    cd ~/development
    unzip ~/Downloads/flutter_macos_v0.5.1-beta.zip
    
  • 3.添加flutter相关工具到path中:
    export PATH=`pwd`/flutter/bin:$PATH
    
  • 此代码只能暂时针对当前命令行窗口设置PATH环境变量,要想永久将Flutter添加到 PATH 中请参考下面更新环境变量 部分

2.) 配置镜像:

  • 由于在国内访问Flutter有时可能会受到限制,Flutter官方为中国开发者搭建了临时镜像,大家可以将如下环境变量加入到用户环境变量中:
    export PUB_HOSTED_URL=https://pub.flutter-io.cn
    export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
    
  • 此镜像为临时镜像,并不能保证一直可用,读者可以参考flutter.dev/community/c… 以获得有关镜像服务器的最新动态
  • 在masOS下可以同时进行Android和iOS设备的测试
  • 系统要求
    • 要安装并运行Flutter,开发环境必须满足以下最低要求: 操作系统: macOS (64-bit)
    • 磁盘空间: 700 MB (不包括 XcodeAndroid Studio的磁盘空间).
    • 工具: Flutter 依赖下面这些命令行工具
      bashmkdirrmgitcurlunzipwhich

3. 检查Flutter环境安装情况

flutter doctor
  • 该命令检查你的电脑环境并在终端窗口中显示报告。
  • Dart SDK已经在捆绑在Flutter里了,没有必要单独安装Dart
  • 仔细检查命令行输出以获取可能需要安装的其他软件或进一步需要执行的任务(以粗体显示)
  • 一般的错误会是xcodeAndroid Studio版本太低、或者没有ANDROID_HOME环境变量等,请按照提示解决。下图是我自己用命令检测的结果,打钩的就是没有问题的,打叉的就是缺少或者是版本有问题的 image.png
    • Flutter doctor报错 Checking Android licenses is taking an unexpectedly long time... 解决方法:
    1. 打开工具菜单,SDK管理器
    2. 选择安卓SDK栏目,顶部选择SDK Tools,选中'Android SDK Command-line Tools'选项,点击OK进行安装
    3. 终端输入下面命令,出现提示全部输入y即可
      flutter doctor --android-licenses
      
  • 此时再输入 flutter doctor,依然报了一个警告:
    [!] Proxy Configuration
        ! NO_PROXY is not set
    
    image.png
    • 解决方法:在终端输入:
    export NO_PROXY=localhost,127.0.0.1,::1
    

开启模块

  • flutter config --enable-web
  • flutter config --enable-macos-desktop
  • flutter config --enable-windows-desktop

关闭模块

  • flutter config --no-enable-web
  • flutter config --no-enable-macos-desktop
  • flutter config --no-enable-windows-desktop

4. 配置iOS环境

5. 配置Android环境

6. 开发工具选择

7. Android Studio

8. 在Windows上搭建Flutter开发环境

我没有Windows电脑,需要搭建Windows系统的Flutter环境,需要按照官网的指引文件来操作:docs.flutter.dev/get-started…

五、创建Flutter项目

1. 创建项目

有两种方式创建Flutter应用:

  • 通过终端命令行
  • 通过编辑器(VS Code)/IDE(Android Studio)

1.1 命令行 创建项目

这里我先选择通过终端(Windows和macOS都是一样的命令

检查本地Flutter环境

flutter 新建项目之前,我们先检查一下自己的flutter环境是否有问题:

flutter doctor

flutter doctor命令检查环境是否有问题

从命令的运行来看,是没有任何的错误❌,说明flutter 的环境是 OK 的

创建项目

flutter create 项目名
# 示例:
# flutter create hello_flutter
# 注意:后面的名称不能由特殊符号,也不能由大写

我们尝试用flutter create helloFlutter命令来新建一个项目工程吧!

image.png

从报错信息来看,是我们的项目名称出了问题,

合法项目名称

helloFlutter" 不是有效的 Dart 包名称
why ? 大大的问号,这个名称没有问题啊,为什么就不支持呢?因为我们习惯了驼峰命名
但是 Dart是不支持驼峰命名的!既然不支持驼峰命名,那么就换个名称(helloflutter)吧!

新建项目成功

image.png

那么就按照提示,cd helloFlutter打开项目目录,flutter run把项目跑起来看看吧!

1.2 运行flutter 项目open

第一次运行有点慢,会对环境进行一下检查,之后运行就会快很多了。 image.png

  • 第一次运行完成之后,会有如下提示:有一下运行的时候,还有一些快捷键的使用! image.png
  • 在模拟器中运行的界面如下: image.png
  • flutter 工程文件结构如下: image.png

目录里面安卓和 iOS 工程都有,一份代码,多端使用👍🏻!

运行效果

1.3 xcode 打开 flutter 工程

因为 flutter 是跨平台的,里面包含了安卓和 iOS 工程,我们双击打开iOS 工程就可以了,默认生成的是 Swift 的工程。

image.png

打开 iOS 工程如下所示: image.png

Xcode运行iOS 工程如下所示: image.png

默认ios 是 Swift 的工程,安卓 kotlin,我们也是可以去修改创建的工程语言的,使用flutter create --help命令就可以查看

查看帮助

那么现在就去创建一个 OC 的工程吧,使用flutter create -i objc flutter_objcdemo命令。

OC 工程

提示

我们都是使用 Xcode 去签名/真机调试,不会使用 Xcode 去写 flutter,它也不支持 dart 语言啊!

1.2 Android Studio 新建项目

Android Studio 新建项目

image.png

Android Studio 新建flutter项目

image.png

点击创建 flutter 项目,进入如下界面

image.png

填写项目名称,项目的语言,支持的平台等!(这里我就不新建了,我就直接打开之前的项目了!)

Android Studio中 flutter 项目结构

目录结果和文件夹中的是一样的,顺序几乎都是一样的,我们在 lib文件夹下面写 dart代码。

可以下拉选择模拟器运行项目

Android Studio中下拉选择模拟器

在终端中也是打开模拟器open -a Simulatoer,如果有多个模拟器会提示选择一个来运行项目,如下图所示:

如果有多个模拟器会提示选择一个来运行项目

选择其中一个模拟器来运行 flutter 项目

选择一个模拟器项目运行

1.3 VS Code 新建项目

打开VS Code命令面板

Cmd + shift + p(或者View>Command Palette ...)  
输入 Flutter: New project

选择并输入项目名称回车,选择存放路径

便初始化了一个flutter demo工程。

2. 项目跑在模拟器

通过一个你喜欢的开发工具打开(我这里暂时选择Android Studio)

image-20190830165738248

选择你要启动的设备,点击 运行 按钮:

image-20190830170112928

我把项目运行在了两个模拟器上

image-20190830170814213

3. 体验Flutter热重载

对于我们开发测试阶段,如果每次修改代码都需要重新编译整个项目再加载的话,那每次可能都需要花费10秒左右甚至是几分钟的时间(电脑太慢的话),这样的开发效率是非常低的。

现在前端开发都支持热重载(Hot Reload),可以大大加快我们的开发效率。

  • 热重载可以在无需重新编译代码、重新启动应用程序的情况下,看到修改后界面的效果

Flutter在开发阶段使用JIT编译模式(后面我会讲解什么是JIT模式),所以可以做到热重载来提高我们的开发效率

下面我们体会一下热重载,后面有时间我们来分析热重载是如何实现的 将下面红框中的内容改成Hello Flutter,保存一下应用程序

  • 你会发现在不到1秒钟内,界面直接发生了刷新
  • 并且没有应用程序没有进行任何的重新,效率非常高

image-20190830172702931

如果热重载不起作用,我们也可以点击右上角的 Hot Restart,并不需要重新运行项目

image-20190830173033311

4. 工程目录分析

Flutter工程创建完毕会感觉比较复杂,我们来看下图: image.png

目录包含哪些东西呢?

  • 其中包含Flutter开发和测试需要的lib、test,在开发过程中,我们主要使用的就是lib目录
  • 另外一些是管理项目的配置文件信息等,当然也包括一些Git相关的文件
  • 除此之外,还包括一个Android子工程和iOS子工程

为什么包含Android子工程和iOS子工程呢?

  • 这是因为作为一个跨平台的开发方案,最终还是要嵌入到Android工程或者iOS工程中来运行的

  • 并且在开发过程中也需要调用原生的一些功能