1. Package 介绍
通过使用 packages (的模式)可以创建易于共享的模块化代码。一个最基本的 package 由以下内容构成:
pubspec.yaml
文件:用于定义 package 名称、版本号、作者等其他信息的元数据文件。- 包含共享代码的
lib
目录,其中至少包含一个<package-name>.dart
文件。
备忘
有关编写高效插件的注意事项列表,请参考 Medium 上的文章:Writing a good plugin。
1.1 Package 类别
Package 包含以下两种类别:
- 纯 Dart 库:用 Dart 编写的传统 package,比如
path
。其中一些可能包含 Flutter 的特定功能,因此依赖于 Flutter 框架,其使用范围仅限于 Flutter,比如fluro
。 - 原生插件:使用 Dart 编写的,按需使用 Java 或 Kotlin、ObjC 或 Swift 分别在 Android 和/或 iOS 平台实现的 package。一个具体的例子是
battery
。
2. 开发纯 Dart 库的 packages
步骤1:创建 package
想要创建纯 Dart 库的 package,请使用带有 --template=package
标志的 flutter create
命令:
这将在 hello/
目录下创建一个 package 项目,其中包含以下内容:
lib/hello.dart
package 的 Dart 实现代码。
步骤2: 实现 package
对于纯 Dart 库的 package,只要在
lib/<package name>.dart
文件中添加功能实现,或在
lib
目录中的多个文件中添加功能实现。
3. 开发原生插件类型的 packages
如果想要开发一个调用特定平台 API 的 package,你需要开发一个原生插件 packgae。原生插件 packgae 是 Dart package 的特别版本,除了要实现 Dart package 要实现的内容,还需要按需使用 Java 或 Kotlin、ObjC 或 Swift 分别在 Android 和/或 iOS 平台实现,你可以使用 platform channel 中的 API 来实现特定平台的调用。
platform channel链接:
步骤1: 创建 package
想要创建原生插件 package,请使用带有
--template=plugin
标志的
flutter create
命令。
使用
--org
选项,以反向域名表示法来指定你的组织。该值用于生成的 Android 及 iOS。
这将在
hello/
目录下创建一个插件项目,其中包含以下内容:
-
lib/hello.dart
:
Dart 插件 API 实现。
android/src/main/java/com/example/hello/HelloPlugin.kt
:
Android 平台原生插件 API 实现。
ios/Classes/HelloPlugin.m
:
iOS 平台原生插件 API 实现。
example/
:
一个依赖于该插件并说明了如何使用它的 Flutter 应用。
默认情况下,插件项目中 iOS 代码使用 Swift 编写,Android 代码使用 Kotlin 编写。如果你更喜欢 Objective-C 或 Java,你可以通过
-i
指定 iOS 所使用的语言和/或使用
-a
指定 Android 所使用的语言。比如:
步骤2: 实现 package
由于原生插件类型的 package 包含了使用多种编程语言编写的多个平台代码,因此需要一些特定步骤来保证体验的流畅性。
步骤 2a:定义 package API(.dart)
步骤 2b:添加 Android 平台代码(.java/.kt)
我们建议你使用 Android Studio 来编辑 Android 代码。
使用 Android Studio 编辑 Android 平台代码之前,首先确保代码至少被构建过一次(换句话说,即从 IDE/编辑器执行示例程序,或在终端中执行以下命令:
cd hello/example; flutter build apk
)。
接下来,
(1)启动 Android Studio
(2)在“Welcome to Android Studio”对话框中选择“Import project”,或在菜单中选择“File > New > Import Project…”,然后选择
hello/example/android/build.gradle
文件;
(3)在“Gradle Sync”对话框中,选择“OK”;
(4)在“Android Gradle Plugin Update”对话框中,选择“Don’t remind me again for this project”。
插件的 Android 平台代码位于
hello/java/com.example.hello/HelloPlugin
。
你可以在 Android Studio 中点击 ▶ 按钮来运行示例程序。
步骤 2c:添加 iOS 平台代码(.h+.m/.swift)
我们建议你使用 Xcode 来编辑 iOS 代码。
使用 Xcode 编辑 iOS 平台代码之前,首先确保代码至少被构建过一次(即从 IDE/编辑器执行示例程序,或在终端中执行以下命令:
cd hello/example; flutter build ios --no-codesign
)。
下一步
(1)启动 Xcode
(2)选择“File > Open”,然后选择
hello/example/ios/Runner.xcworkspace
文件。
插件的 iOS 平台代码位于项目导航中的
Pods/Development Pods/hello/Classes/
。
你可以点击 ▶ 按钮来运行示例程序。
步骤 2d:关联 API 和平台代码
最后,你需要将 Dart 编写的 API 代码与特定平台的实现相互关联。
4. 添加文档
建议将下列文档添加到所有 package 中:
(1)
README.md
文件用来对 package 进行介绍
(2)
CHANGELOG.md
文件用来记录每个版本的更改
(3)
LICENSE
文件用来阐述 package 的许可条款
(4)API 文档包含所有的公共 API(详情参见下文)
4.1 API 文档
当你提交一个 package 时,会自动生成 API 文档并将其提交到 dartdocs.org,示例请参见
device_info docs
如果你希望在本地开发环境中生成 API 文档,可以使用以下命令:
(1)将当前工作目录切换到 package 所在目录:
cd ~/dev/mypackage
(2)告知文档工具 Flutter SDK 所在位置(更改以反应它所在的位置):
export FLUTTER_ROOT=~/dev/flutter
(适用于 macOS 或 Linux 操作系统)
set FLUTTER_ROOT=~/dev/flutter
(适用于 Windows 操作系统)
(3)运行
dartdoc
工具(作为 Flutter SDK 的一部分):
$FLUTTER_ROOT/bin/cache/dart-sdk/bin/dartdoc
(适用于 macOS 或 Linux 操作系统)
%FLUTTER_ROOT%\bin\cache\dart-sdk\bin\dartdoc
(适用于 Windows 操作系统)
4.2 将许可证添加到 LICENSE 文件中
每个 LICENSE 文件中的各个许可证应由 80 个短线字符组成的线段进行分割。
如果 LICENSE 文件中包含多个组件许可证,那么每个组件许可证必须以其所在 package 的名称开始,每个 package 名称单独一行显示,并且 package 名称列表与实际许可证内容由空行隔开。(package 名称无需与 pub package 相匹配。比如,一个 package 可能包含多个第三方代码,并且可能需要为每个 package 添加许可证。)
正确:
package_1
<some license text>
--------------------------------------------------------------------------------
package_2
<some license text>
正确:
package_1
<some license text>
--------------------------------------------------------------------------------
package_1
package_2
<some license text>
不正确:
<some license text>
--------------------------------------------------------------------------------
<some license text>
不正确:
package_1
<some license text>
--------------------------------------------------------------------------------
<some license text>
5. 提交 package
一旦完成了 package 的实现,你便可以将其提交到
pub.dev
上,以便其他开发者可以轻松地使用它。
提交之前,请确保
pubspec.yaml
、
README.md
以及
CHANGELOG.md
文件已被审查,以保证其内容的完整性和正确性。
接下来,运行 dry-run 命令以检验是否所有内容都通过了分析:
最后,运行以下提交命令:
6. Package 依赖处理
如果你正在开发的
hello
依赖于另外一个 package 所公开的 Dart API,你需要将该 package 添加到文件
pubspec.yaml
的
dependencies
段中。以下代码使得插件
url_launcher
的 Dart API 在
hello
中可用:
在
hello/pubspec.yaml
文件中:
dependencies:
url_launcher: ^0.4.2
现在你可以在
hello
的 Dart 代码中使用
import 'package:url_launcher/url_launcher.dart'
和
launch(someUrl)
。
这与你在 Flutter 应用或其他任何 Dart 项目中引入 package 的方式没什么区别。
但碰巧
hello
是一个 原生插件 package,其特定的平台代码如果需要访问
url_launcher
所公开的平台特定 API,那么还需要为特定平台的构建文件添加适当的依赖说明,如下所示:
6.1 Android
在
hello/android/build.gradle
文件中:
android {
// lines skipped
dependencies {
provided rootProject.findProject(":url_launcher")
}
}
现在你可以在
hello/android/src
目录下的源代码文件中使用
import io.flutter.plugins.urllauncher.UrlLauncherPlugin
并访问类
UrlLauncherPlugin
。
6.2 iOS
在
hello/ios/hello.podspec
文件中:
Pod::Spec.new do |s|
# lines skipped
s.dependency 'url_launcher'
现在你可以在
hello/ios/Classes
目录下的源代码文件中使用
#import "UrlLauncherPlugin.h"
并访问
UrlLauncherPlugin
这个类了。