Flutter包开发和发布以及使用

https://dart.cn/guides/libraries/create-library-packages

创建一个包项目

1.Android Studio: File>New>New Flutter Project 来创建一个Package工程

2.intellij Idea: File>New>Project>Flutter>Project type select package

3.flutter create --template=package hello

包含 :
lib/hello.dart:Package的Dart代码
test/hello_test.dart:Package的单元测试代码。

实现功能

例(shelf Package的目录结构)

Package中主要的功能的源码都在src目录下。shelf Package也导出了一个迷你库: shelf_io,它主要是处理HttpRequest的。
在lib根目录下的“shelf.dart”中,导出了多个“lib/src”目录下的dart文件:

1
2
3
4
5
6
7
8
9
10
export 'src/cascade.dart';
export 'src/handler.dart';
export 'src/handlers/logger.dart';
export 'src/hijack_exception.dart';
export 'src/middleware.dart';
export 'src/pipeline.dart';
export 'src/request.dart';
export 'src/response.dart';
export 'src/server.dart';
export 'src/server_handler.dart';

生成文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1. README.md
介绍包
2. CHANGELOG.md
记录每个版本中的更改
3. LICENSE
许可条款
4. 所有公共API的API文档
在发布软件包时,API文档会自动生成并发布到dartdocs.org

可使用 dartdoc 工具来为Package生成文档。开发者只需要遵守文档注释语法,在代码中添加文档注释,最后使用dartdoc生成API文档(一个静态网站)。文档注释是使用三斜线"///"开始,如:
/// The event handler responsible for updating the badge in the UI.
void updateBadge() {
...
}
5. pubspec.yaml (引用插件,版本号和主页,没有写主页好像发布不上去,会提示你要加个主页)
name: untitled2
description: A new Flutter project.
version: 0.0.1
homepage: https://github.com/sss/xxx

包的发布

  1. 检查pubspec.yaml、README.md以及CHANGELOG.md文件,以确保其内容的完整性和正确性。
  2. 运行 dry-run 命令(查看是否都准备OK):
    flutter packages pub publish --dry-run
  3. 验证无误后,发布
    flutter packages pub publish

第一步:会提示输入 y

第二步:点击链接校验,需要登录谷歌账号校验下。

第三步:等待发布成功。会收到邮件。

如果发布失败,一直等待,需要翻墙。

如果 flutter packages pub publish 命令不行, 使用 flutter packages pub publish -v

配置文件.bash_profile 把注释,

1
2
#export PUB_HOSTED_URL=https://pub.flutter-io.cn
#export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

记得 source ~/.bash_profile 让环境变量生效

最后发布:可以让终端代理生效。

如果遇到包发布失败的情况,先检查是否因为众所周知的网络原因,如果是网络问题,可以使用VPN,这里需要注意的是一些代理只会代理部分APP的网络请求,如浏览器的,它们可能并不能代理dart的网络请求,所以在这种情况下,即使开了代理也依然无法连接到Pub,因此,在发布Pub包时使用全局代理或全局VPN会保险些。如果网络没有问题,以管理员权限(sudo)运行发布命令重试。
很多时候开启全局代理也不会让terminal中的流量打代理服务器走,以socks5为例,应该在终端下输入以下指令:
export all_proxy=socks5://127.0.0.1:1080

使用包

添加依赖包

1
2
dependencies: 
hello:^1.1.0

通过"package:"指令来指定包的入口文件

1
import 'package:hello/hello.dart';

处理包的相互依赖

如果正在开发一个hello包,它依赖于另一个包,则需要在hello/pubspec.yaml的dependencies中添加该依赖包:

1
2
dependencies: 
url_launcher: ^0.4.2

现在可以在hello中import 'package:url_launcher/url_launcher.dart' 然后调用 launch()方法了。

但是,如果hello碰巧是一个插件包,其平台特定的代码需要访问url_launcher公开的特定于平台的API,那么还需要为特定于平台的构建文件添加合适的依赖声明:

Android
在 hello/android/build.gradle:

1
2
3
4
5
6
android {
// lines skipped
dependencies {
provided rootProject.findProject(":url_launcher")
}
}

现在可以在hello/android/src源码中import io.flutter.plugins.urllauncher.UrlLauncherPlugin访问UrlLauncherPlugin类。

iOS
在hello/ios/hello.podspec:

1
2
3
Pod::Spec.new do |s|
# lines skipped
s.dependency 'url_launcher'

现在可以在hello/ios/Classes源码中 #import "UrlLauncherPlugin.h" 然后访问 UrlLauncherPlugin类。

解决依赖冲突

假设在hello包中使用some_package和other_package,并且这两个包都依赖url_launcher,但是依赖的是url_launcher的不同的版本,这就有潜在的冲突了。

方法1(最好)
在指定依赖关系时,使用版本范围而不是特定版本,pub将能够自动解决问题。

1
2
3
dependencies:
url_launcher: ^0.4.2 # 较好, 任何0.4.x(x >= 2)都可.
image_picker: '0.1.1' # 不好,只有0.1.1版本.

方法2
添加依赖覆盖声明,从而强制使用特定版本

1
2
3
4
dependencies:
some_package:
dependency_overrides:
url_launcher: '0.4.3'

如果冲突的依赖不是一个包,而是一个特定于Android的库,比如guava,那么必须将依赖重写声明添加到Gradle构建逻辑中。
强制使用23.0版本的guava库,在hello/android/build.gradle中:

1
2
3
4
5
configurations.all {
resolutionStrategy {
force 'com.google.guava:guava:23.0-android'
}
}

Cocoapods目前不提供依赖覆盖功能。