1. 包和插件
包
一个最小的包(Package)包括:
- 一个
pubspec.yaml文件:声明了Package的名称、版本、作者等的元数据文件。 - 一个
lib文件夹:包括包中公开的(public)代码,最少应有一个<package-name>.dart文件
配置文件pubspec.yaml(位于项目根目录)来管理第三方依赖包
name: flutter_in_action
description: First Flutter Application.
version: 1.0.0+1
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
name:应用或包名称。description: 应用或包的描述、简介。version:应用或包的版本号。dependencies:应用或包依赖的其它包或插件。dev_dependencies:开发环境依赖的工具包(而不是flutter应用本身依赖的包)。flutter:flutter相关的配置选项。
如果我们的Flutter应用本身依赖某个包,我们需要将所依赖的包添加到dependencies 下,接下来我们通过一个例子来演示一下如何添加、下载并使用第三方包。
比如网络请求
dependencies:
flutter:
sdk: flutter
english_words: ^3.1.0
http: ^0.13.4
Flutter 包分为两类
- Dart包:其中一些可能包含Flutter的特定功能,因此对Flutter框架具有依赖性,这种包仅用于Flutter,例如
fluro包。 - 插件包:一种专用的Dart包,其中包含用Dart代码编写的API,以及针对Android(使用Java或Kotlin)和针对iOS(使用OC或Swift)平台的特定实现,也就是说插件包括原生代码,一个具体的例子是
battery插件包。
插件
Flutter 本质上只是一个 UI 框架,运行在宿主平台之上,Flutter 本身是无法提供一些系统能力,比如使用蓝牙、相机、GPS等,因此要在 Flutter 中调用这些能力就必须和原生平台进行通信。目前Flutter 已经支持 iOS、Android、Web、macOS、Windows、Linux等众多平台,要调用特定平台 API 就需要写插件。插件是一种特殊的包,和纯 dart 包主要区别是插件中除了dart代码,还包括特定平台的代码,比如 image_picker 插件可以在 iOS 和 Android 设备上访问相册和摄像头。 (这点很重要,因为后面要学到蓝牙开发,以及iOS安卓两端的适配。)
如何获取平台信息(这个也很重要)
有时,在 Flutter 中我们想根据宿主平台添加一些差异化的功能,因此 Flutter 中提供了一个全局变量 defaultTargetPlatform 来获取当前应用的平台信息,defaultTargetPlatform定义在"platform.dart"中,它的类型是TargetPlatform,这是一个枚举类,定义如下:
enum TargetPlatform {
android,
fuchsia,
iOS,
...
}
目前Flutter只支持这三个平台。我们可以通过如下代码判断平台:
if(defaultTargetPlatform == TargetPlatform.android){
// 是安卓系统,do something
}
由于不同平台有它们各自的交互规范,Flutter Material库中的一些组件都针对相应的平台做了一些适配,比如路由组件MaterialPageRoute,它在android和ios中会应用各自平台规范的切换动画。那如果我们想让我们的APP在所有平台都表现一致,比如希望在所有平台路由切换动画都按照ios平台一致的左右滑动切换风格该怎么做?Flutter中提供了一种覆盖默认平台的机制,我们可以通过显式指定
debugDefaultTargetPlatformOverride=TargetPlatform.iOS;
print(defaultTargetPlatform); // 会输出TargetPlatform.iOS
上面代码即在Android中运行后,Flutter APP就会认为是当前系统是iOS,Material组件库中所有组件交互方式都会和iOS平台对齐,defaultTargetPlatform的值也会变为TargetPlatform.iOS。
Flutter 官方提供了一系列常用的插件,如访问相机/相册、本地存储、播放视频等,完整列表见:github.com/flutter/plu… 读者可以自行查看。除了官方维护的插件,Flutter 社区也有不少现成插件,具体读者可以在 pub.dev/ 上查找。
2. Flutter Web
简介
Flutter 目前已经支持macOS、Windows、Linux、Android、iOS、Web等多个平台这些平台中除了Web平台会比较特殊一些,因为除了它其余的“平台”都是操作系统,而 Web 并不是操作系统,Web应用程序是运行在浏览器中的,而浏览器是运行在操作系统之上,因此 “平台”一词,指的是某种“运行环境”,并不等同于“操作系统”,浏览器和操作系统都是应用程序运行的环境而已。
传统的 Web 应用都是基于 Javascript+html+css 开发的,运行在浏览器之上,因此天然具备跨平台优势,而 Flutter 的目标是高性能的跨端 UI 框架,所以支持 Web 平台将有助于 Flutter 技术扩大应用场景,实现 write once, run anywhere。为此,Flutter 团队从 1.0 开始一直在尝试让 Flutter 支持 Web 平台,第一个支持 Web 平台的稳定版是 2.0 ,在 2.0 之后 Flutter 对 Web 平台的支持也一直在优化,现在也有一些公司将Flutter应用应用到生产环境。
Web 应用的特殊性
因为 Web 应用是在浏览器中运行的,而浏览器是运行在操作系统之上,因此Web应用不能直接调用操作系统 API, Web 应用能调用哪些操作系统能力取决于它的宿主-浏览器是否暴露相关的操作系统 API。而浏览器出于安全考虑,会提供一个沙箱环境——开放一些安全、可控的系统能力,同时限制一部分敏感的操作,具体表现在:
- 浏览器允许Web应用访问网络,但有严格的“同源策略”限制。
- 浏览器允许 JavaScript 读取用户手动选择本地文件(文件上传场景),但不允许 JavaScript 主动访问本地文件系统,同时在任何情况下,浏览器都不允许 JavaScript 直接往本地文件系统写文件,因此
dart:io包在 Web 应用是不能用的。 - 浏览器对Web应用访问系统硬件权限有自身策略,比如访问 wifi、gps、摄像头等。
因此,如果用 Flutter 开发 Web 应用,以上这些限制将会生效,所以会出现和其它平台不一致的情况,常见的两个场景是:不能在 Web 应用中发起非同源请求、不能在Web应用中直接读取文件。
“同源策略” 是浏览器处于安全考虑对 Web 应用访问网络的一套限制策略, “同源”表示一个网页中 JavaScript 发起网络请求的地址和当前网页地址中协议、域名、端口全部相同,如果有其中之一不同,则为“非同源”,如果不进行特殊处理,浏览器会禁止非同源请求。关于“同源策略”的详细内容以及如何访问非同源请求读者可以自己上网搜索,这在 Web 开发中是一个非常基础的知识点,网上资料很多,不再赘述。
Web 渲染器
Flutter 中提供了两种不同的渲染器来运行和构建 Web 应用,分别是 html 渲染器和 CanvasKit 渲染器。
Html渲染器
由于浏览器有一套自身的布局标准( html+css ),Flutter在生成Web应用时可以编译为符合浏览器标准的文件,包括使用 HTML,CSS,Canvas 和 SVG 元素来渲染。
使用Html渲染器的优点是应用体积相对较小,缺点是使用Html渲染器时大多数 UI 并不是 Flutter 引擎绘制的,所以可能会存在跨浏览器跨时UI出现不一致的情况。
CanvasKit 渲染器
Flutter 的优势是提供一套自绘的UI框架,可以保证多端UI的一致性。Flutter 在支持其它平台时,都是将引擎的C++代码编译为相应平台的代码来实现移植的(运行在操作系统之上)。但是在 Web 平台,Web 应用是运行在浏览器之上,而现代浏览器都实现了对 WebAssembly 的支持,简单来讲,在之前W3C规范中只要求浏览器能够支持 JavaScript 语言,这样的话很多其它语言的代码想在浏览器中运行就必须改写为 JavaScript,而 WebAssembly 是一种标准的、可移植的二进制文件格式规范,文件扩展名为 .wasm,现在浏览器都支持 WebAssembly ,这也就意味着其它语言按照 WebAssembly 规范编译的 .wasm 可以在浏览器中运行!因此,Flutter 将引擎编译成 WebAssembly 格式,并使用 WebGL 渲染,这种渲染方式的渲染器官方称为 CanvasKit 渲染器。
CanvasKit 渲染器的优点是可以保证跨端UI绘制的一致性,有更好的性能,以及降低不同浏览器渲染效果不一致的风险。但缺点是应用的大小会增加大约 2MB
在浏览器中运行
命令行参数
--web-renderer 可选参数值为 auto、html 或 canvaskit。
auto(默认)- 自动选择渲染器。移动端浏览器选择 HTML,桌面端浏览器选择 CanvasKit。html- 强制使用 HTML 渲染器。canvaskit- 强制使用 CanvasKit 渲染器。
此选项适用于 run 和 build 命令。例如:
flutter run -d chrome --web-renderer html
flutter build web --web-renderer canvaskit
如果运行/构建目标是非浏览器设备(即移动设备或桌面设备),这个选项会被忽略。
Flutter Web 使用场景
Web 开发已有完整且强大的开发及生态体系,Flutter Web并不适用Web开发的所有场景,目前Flutter Web 主要关注以下三个应用场景:
- 渐进式 Web 应用 (Progressive web apps, PWA)。
- 单页应用 (Single page apps, SPA),一般一个应用只有一个html文件,不同页面是通过。
- 将现有 Flutter 移动应用拓展到 Web,在两个平台共享代码。
现在阶段,Flutter 对于富文本和瀑布流类型的 Web 页面并不是很适合,例如博客,它是典型的“以文档为中心”的模式,而不是像 Flutter 这样的 UI 框架可以提供的“以应用为中心”的服务。以文档为中心的应用通常各个页面之间相互独立,很少有关联,也就不需要跨页面的状态共享,而以应用为中心的服务,通常各个页面之间是有状态关联,不同页面组成一个完整的功能。