Dart Pub 里的 Flutter 插件库都是兼容 Android 和 iOS 的,当然 Dart Pub 里的插件库还有很多是 Web 相关的插件,我们只需要搜索 Flutter 的插件库使用即可。
我们看下 Flutter 相关的使用频率比较高的插件库:
我们这里以 path_provider 这个插件库为例,点击 path_provider 这个链接进入插件库详情描述页。path_provider 是用于为 Flutter 提供访问 Android 和 iOS 的文件系统目录的功能的一个插件库。
点击进入的页面如下:
有说明文档、更新日志、例子、安装步骤、版本列表、关于页面、插件官方首页、Github 地址、相关问题页面、API 文档等等信息。
我们需要点击 Installing,复制安装依赖库的信息到 pubspec.yaml:
dependencies:
path_provider: ^1.1.2
接下来我们可以在 Readme 或者 Example 里看到使用的方法和说明,如果没有的话,可以点击进入官方的 Github 进行下载和查看使用的实例。
我们除了可以使用 Dart Pub 上提供的插件库以外,如果遇到 Dart Pub 上的插件库也没有办法实现我们想要的功能的时候,我们可以自己编写插件库,需要兼容 Android 和 iOS 平台,也就是要分别写 Android 和 iOS 原生代码,并提供给 Flutter 进行调用。当然,我们也可以将我们的插件库提交到 Dart Pub 上供其他人使用。
那么接下来我们就来看看如何编写 Flutter 插件库,并提交到 Dart Pub 上。
Flutter 的 Dart Pub 上的插件库主要分为两种:一种是包(Flutter Package):纯 Dart 编写的 API 插件库;另一种就是插件(Flutter Plugin):编写 Android、iOS 的原生代码,然后通过 Flutter 的 MethodChannel 来调用封装好的对应平台的原生代码来实现的插件库。
这两种插件库各有各的特点和功能,我们的 Android Studio 在创建项目时,也提供了插件库创建的两种方式:
我们可以看到有 Flutter Plugin 和 Flutter Package 两种方式来创建插件库。相应地,如果我们的插件库通过纯 Dart 就可以实现这个插件功能的话,就选择 Flutter Package 方式创建插件库;如果我们的插件库必须借助 Android、iOS 平台的原生代码才可以实现插件功能的话,那么就选择 Flutter Plugin 方式创建我们的插件库。
我们先看下 Flutter Package 这种方式创建插件库。
除了可以用 Android Studio 进行界面操作创建外,我们还可以通过命令行方式创建:
$ flutter create --template=package hello
这里的 hello
为插件 Package 名称,英文名称。
我们看下创建后的项目结构:
插件的逻辑写在 lib 目录下,纯 Dart 实现的功能逻辑。
test 目录下面是单元测试文件。
CHANGELOG.md 这个文件是用于描述插件更新的日志的。提交到 Dart Pub 上就是 CHANGELOG 这里显示的内容。
LICENSE 是添加我们的开源插件库所遵循的开源协议是哪些,及其描述。
pubspec.yaml 这里面是我们插件库的描述信息,如插件库名称信息、作者信息、版本信息等其他信息。
我们大致看下 pubspec.yaml 的内容:
// 插件库名称
name: flutter_package
// 插件库描述
description: A new Flutter package.
// 插件库版本
version: 0.0.1
// 作者信息,名字 <邮箱>形式
author: Tan Dong <tandongjay@qq.com>
// 插件库的主页
homepage: https://github.con/tandong/flutter_package
// 插件库运行的sdk版本环境
environment:
sdk: ">=2.1.0 <3.0.0"
// 所需要的依赖
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
README.md 是插件库的说明文档,包含插件库的功能描述、特点、用法示例等等说明描述性的信息。
当我们的项目具备这些文件和目录结构后,并且在 lib 目录下编写完 dart 功能代码后,我们就可以自己使用了,如果想共享给其他人,就可以发布到 Dart Pub 上。
fluro 这个插件库就是一个 Flutter Package 实现的插件库:https://pub.dev/packages/fluro ,大家可以参考学习下它的结构。
例如,假如我们的插件库名叫做:flutter_package,那么我们默认就会在 lib 目录下新建一个 flutter_package.dart 文件,建议 lib 根目录的文件名为插件库英文名字命名。
入口文件示例:
library flutter_package;
/// A Calculator.
class Calculator {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
}
顶部:library + 插件库名字声明。
下面就可以编写相关的 class 和方法类逻辑了。
发布到 Dart Pub
如果我们的项目结构都完整,包含了 lib、pubspec.yaml、README.md 以及 CHANGELOG.md 等文件,我们就可以发布到 Dart Pub 了。
运行如下命令,检查是否一切就绪并且正确:
$ flutter packages pub publish --dry-run
如果检查通过的话,输入如下命令即可发布:
$ flutter packages pub publish
这样就完成了我们 Flutter Package 的发布。
依赖冲突的解决
如果遇到插件库的依赖库引用冲突,如版本不一致,插件库使用了一个版本的依赖库、项目中又引入了另一个版本的插件库,这时可能会产生冲突。
Flutter 官方建议我们的插件库所用的依赖库版本声明中,要声明使用范围,而不是指定某个固定版本号。
例如我们的 flutter_package 插件库的 pubspec.yaml 中声明了依赖:
dependencies:
url_launcher: ^0.4.2
这样使用范围的声明是推荐的,而不是指定固定一个版本的 url_launcher。
还有一种方式解决冲突:
dependencies:
some_package:
other_package:
dependency_overrides:
url_launcher: '0.4.3'
就是强制使用 dependency_overrides
来指定统一 url_launcher 依赖库的版本。
接下来我们看下有了原生代码逻辑的 Flutter Plugin 的插件库的开发。若我们的插件库使用纯Dart 无法实现的话,那么就要通过编写各个平台的原生代码来实现交互调用了。这种方式就是 Flutter Plugin 方式的实现。
这次创建插件库项目我们选择 Flutter Plugin 来创建:
也可以使用命令创建:
$ flutter create --org com.example --template=plugin hello
这里建议使用 Android Studio 进行创建。
语言这里我们可以选择使用 Kotin 或者 Swift。默认是 Java 和 Object-C。
当然我们也可以在命令行中指定开发语言:
$ flutter create --template=plugin -i swift -a kotlin hello
创建后的 Flutter Plugin 项目结构如下:
可以看到:
主要的结构和文件就是这些,和 Flutter Package 大同小异。
具体的 Flutter 调用原生的代码逻辑和 Android 及 iOS 平台的代码编写逻辑。
Flutter 与原生交互:
例如,Flutter 官方的例子实现获取手机电量信息的。其实就是编写了 Android 的方法、iOS 的方法,然后 Flutter 端编写 dart 代码来反射调用对应平台的获取电池电量的方法。
一个典型的 Flutter Plugin 插件例子就是 path_provider 这个官方插件库:
https://pub.dev/packages/path_provider
它分别编写了 Android 和 iOS 的平台代码来获取文件路径,然后 Flutter 端调用封装好的方法。大家可以参考这个来学习:
https://github.com/flutter/plugins/tree/master/packages/path_provider 。
插件库的发布同上面的 Flutter Package 步骤一致。
关于 API documentation,即 API 文档,在发布软件包时,API 文档会自动生成并发布到 dartdocs.org。
文档的生成就是根据我们项目代码中的相关注释来生成的,所以我们只需要在每个类、方法、属性、块等地方按照 Dart 说明注释的规则来编写注释即可。
关于 Flutter 未上传发布的库的引入依赖,我们简单讲解下。
本地插件库引入形式:
dependencies:
plugin1:
path: ../plugin1/
Github 上托管的插件库引入形式:
dependencies:
package1:
git:
url: git://github.com/flutter/packages.git
path: packages/package2