pub
/git
/本地指定依赖库pub
这个包管理工具获取依赖的流程和 lockfile
文件的意义这里的 Flutter 插件,不是 IDE 中的插件,而指的是包含平台特定代码的包,用以提供 Flutter 框架所不支持的一些 Native API 的功能。好比经常使用的 shared_preferences , path_provider 等。java
Flutter 框架为咱们提供了不少 UI 层的控制和支持,但 APP 的功能并不局限在显示上,还须要依赖 Native 平台的支持,好比文件系统,摄像头等硬件调用等。因此Flutter为咱们提供了一个Platform Channel
的机制,使得 Dart 代码能够与 Navtive 代码进行交互。基于Platform Channel
,开发者能够编写本身须要的 Native 功能,在 Dart 代码中统一调用。android
随着Flutter社区的成长和壮大,Flutter Plugin 的数量和质量也在不断提升。当你在开发本身的 App 时,若是遇到依赖 Native 的功能时,不妨先考虑去社区搜索是否有现成的轮子。推荐2个平台:ios
针对 dart 语言的三方库平台,能够选择 Flutter 类型进行搜索,更有针对性,每一个库根据 Popularity ,Health, Maintenance 进行打分,是搜索的首选。首页还列出了十几个 Top Popular 的项目,好比 shared_preferences, url_launcher, path_provider,能够说是基础必备插件。git
以 flutter plugin
为关键字搜索。相对 pub.dartlang
,缺乏针对性和评分体系(能够根据 issue
和 star
数进行评估,但相对来讲没有那么直观),但库数量更多,更新更快(好比修复了 bug
不须要等它发布到 pub
上)。github
不一样平台的插件,依赖的写法也有不一样,下文会说明。shell
搜索到本身所需功能的插件后,咱们就直接拿来主义吗?对待开源三方库,个人倾向是先作多方对比,尝试阅读源码,作到心中有数后再引入。在咱们团队,若是须要引入三方库,都必须提供一个说明文档,进行引入缘由说明。swift
考量要点:缓存
若是你发现这个库部分知足了业务需求,你能够选择改进它,或者从新造轮子。若是你以为库维护者比较勤快和靠谱,项目的底子也不错,能够尝试 Fork
这个项目,并给它提 PR
。bash
对编写插件感兴趣的童鞋能够看看这个姊妹篇:Flutter插件编写必知必会。服务器
打开项目下的pubspec.yaml
文件,在 dependencies
下添加依赖名称和版本等信息
在命令行下运行flutter packages get
,或者在 IDE
中 点击 Packages Get
等待它下载完成,并生成插件注册代码
Android:
android/app/scr/main/java/io/flutter/plugins
目录下自动生成的GeneratedPluginRegistrant.java
中,会添加插件的注册代码。public final class GeneratedPluginRegistrant { public static void registerWith(PluginRegistry registry) { if (alreadyRegisteredWith(registry)) { return; } UrlLauncherPlugin.registerWith(registry.registrarFor("io.flutter.plugins.urllauncher.UrlLauncherPlugin")); ... } ... } 复制代码
MainActivity
建立时会去调用这个注册方法class MainActivity : FlutterActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) GeneratedPluginRegistrant.registerWith(this) } } 复制代码
iOS
ios/Runner
目录下自动生成的GeneratedPluginRegistrant.m
中,会添加插件的注册代码。#import "GeneratedPluginRegistrant.h"
#import <url_launcher/UrlLauncherPlugin.h>
@implementation GeneratedPluginRegistrant
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
[FLTUrlLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTUrlLauncherPlugin"]];
}
@end
复制代码
AppDelegate.swift
启动后去调用注册@UIApplicationMain @objc class AppDelegate: FlutterAppDelegate, WXApiDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } 复制代码
在项目文件中 import
所需的包名,并使用
若是依赖中存在 platform-specific code (Java/Kotlin for Android, Swift/Objective-C for iOS),要确保代码可以编译进 App ,必须 Restart App,防止发生MissingPluginException
异常。Hot reload 或者 Hot restart 只对 dart 代码有效。
版本格式:主版本号.次版本号.修订号,版本号递增规则以下:
更详细的参考语义化版本
基本用法:
any # 全部版本,等同于不写。对pub运行性能有影响,不推荐 1.2.3 # 明确的版本号 '>=1.2.3' # 还有 >1.2.3, <=1.2.3, <1.2.3 ^1.2.3 # Caret syntax 等同于 >=1.2.3 <2.0.0 复制代码
注意:若是在版本约束中使用了'>','<'字符,必定要加引号,不然没法被看成 YAML
的语法解析
若是项目依赖了 A
, B
库,他们都依赖了一个 C
,但 C
的版本不一样,可能会产生版本冲突。pub
会尝试找到符合全部依赖约束的版本号。若是找不到能匹配的版本,但 A
,B
库依赖 C
库的 API 是同样的,那么能够添加一个依赖覆盖来强制指定某一版本。
注:pub 是 Dart SDK 提供的一个包管理工具
dependencies: some_package: other_package: dependency_overrides: url_launcher: '0.4.3' 复制代码
若是是 Android 平台的库依赖冲突,能够在 app
的 gradle
文件中强制指定版本
configurations.all { resolutionStrategy { force 'com.google.guava:guava:23.0-android' } } 复制代码
注意: iOS 平台下 CocoaPods 不支持强制版本覆盖
The SDK source is used for any SDKs that are shipped along with packages, which may themselves be dependencies. Currently, Flutter is the only SDK that is supported.
通俗讲,就是 Flutter SDK 自带的库。打开咱们 Flutter 的安装地址,进入flutter/packages
能够看到各类包,如flutter
,flutter_driver
,flutter_test
等。
➜ packages git:(stable) ✗ ls
analysis_options.yaml flutter_localizations
flutter flutter_test
flutter_driver flutter_tools
flutter_goldens fuchsia_remote_debug_protocol
flutter_goldens_client
➜ packages git:(stable) ✗ pwd
/Users/xxx/flutter/packages
复制代码
在 Flutter 项目中写过测试的同窗对上面几个依赖应该不陌生
dependencies: flutter: sdk: flutter # 来源于flutter sdk dev_dependencies: flutter_test: sdk: flutter flutter_driver: sdk: flutter 复制代码
A hosted package is one that can be downloaded from pub.dartlang.org (or another HTTP server that speaks the same API).
dependencies: transmogrify: ^1.4.0 复制代码
dependencies: transmogrify: ^1.4.0 transmogrify: hosted: name: transmogrify url: http://your-package-server.com version: ^1.4.0 复制代码
dependencies: kittens: git: git://github.com/munificent/kittens.git 复制代码
指定分支
dependencies: kittens: url: git://github.com/munificent/kittens.git ref: some-branch 复制代码
pub
默认包目录在 git
仓库的根目录,若是要指定在别的位置,能够用 path
参数
dependencies: kittens: git: url: git://github.com/munificent/cats.git path: path/to/kittens 复制代码
特别适用在一我的同时开发项目和依赖库的状况。由于修改依赖库的代码,在项目中就能够即时生效,有利于调试和提升效率。
dependencies: transmogrify: path: /Users/me/transmogrify # 也能够相对路径,相对路径以 pubspec.yml 文件为基准 复制代码
根据依赖与项目的关系,能够分为如下2类:
immediate dependency
:项目中直接使用的依赖,即咱们在 pubspec
中列出的依赖,包括 dependcies
和 dev_dependencies
transitive dependency
:直接依赖所需的依赖, pub
会根据 pubspec
中列出的依赖自动为咱们获取。好比咱们项目依赖 A
,而 A
又依赖 B
, B
又依赖 C
。那么 A
是咱们项目的immediate dependency
, B
和 C
就是transitive dependency
咱们能够在命令行中输入命令flutter packages pub deps
,查看项目的依赖树。 好比咱们在项目中引入了一个支持网络缓存的图片库cached_network_image: ^0.5.0+1
flutter packages pub deps
Dart SDK 2.1.0-dev.9.4.flutter-f9ebf21297
Flutter SDK 1.0.1-pre.2
your_app_name 2.2.0+10 # 项目名称和版本
|-- cached_network_image 0.5.1 # 直接依赖
| |-- flutter... # 直接依赖(由于在项目pubspec中也添加了)
| '-- flutter_cache_manager 0.2.0+1 # 传递依赖
| |-- flutter...
| |-- http...
| |-- path_provider...
| |-- shared_preferences...
| |-- synchronized 1.5.3
| '-- uuid 1.0.3
| |-- convert...
| '-- crypto...
...
复制代码
根据依赖的做用范围,能够分为:
dependencies
:常规依赖dev dependencies
:开发时所需依赖。它和常规依赖的区别是,项目依赖库中的 dev dependencies
,对于你的项目来讲是不可见的。项目的 pubspec.yml
以下。若是 A
有一个 dev_dependencies
依赖 dev_C
,项目最终的依赖是 A
, dev_B
;不包括 dev_C
。
dependencies: A: dev_dependencies: dev_B: 复制代码
适应场景:若是你须要 import
到 lib
或者 bin
目录,那么选择 dependencies
; 若是你只须要 import
到 test
, example
等,那么就选择 dev dependencies
。使用 dev dependencies
的好处是能让依赖树更小,从而使 pub 运行更快,能跟容易找到知足全部约束的包版本。
在获取一个新的依赖时,pub
会下载知足版本条件的最新版本,而后把版本信息添加到一个 lockfile
中。这个 lockfile
文件叫 pubspec.lock
,位于项目 pubspec.yml
的同级目录。它列出了项目的每一个依赖(包括直接依赖和传递依赖)的版本信息。咱们应该把这个 lockfile
添加到版本控制中,这样不论开发环境,生产环境都能确保使用了相同的依赖版本。
项目的 pubspec.yml
文件包含以下依赖
... dependencies: flutter: sdk: flutter cached_network_image: ^0.5.0+1 dev_dependencies: flutter_test: sdk: flutter ... 复制代码
结合上面提到知识,咱们来看看 pubspec.lock
的内容。 lockfile
把全部依赖树打平,并根据首字母排序
cached_network_image: dependency: "direct main" # 直接依赖,常规依赖 description: name: cached_network_image url: "https://pub.flutter-io.cn" source: hosted version: "0.5.1" flutter: dependency: "direct main" # 直接依赖,常规依赖 description: flutter source: sdk version: "0.0.0" flutter_test: dependency: "direct dev" # 直接依赖,开发依赖 description: flutter source: sdk version: "0.0.0" uuid: dependency: transitive # 传递依赖 description: name: uuid url: "https://pub.flutter-io.cn" source: hosted version: "1.0.3" ... 复制代码
若是非首次获取依赖,pub
会从 lockfile
中读取版本。若是想升级到知足 pubspec.yml
中约束的最新版本,能够执行 flutter packages upgrade
命令,升级后会更新 lockfile
中的版本。
本文咱们主要讨论了插件的获取和选择,同时分析了插件是如何使用并生效的。在介绍插件版本的部分,提到了语义化版本的概念,不论对插件的使用者仍是开发者,都很是有用,推荐你们去细致的看看。对于依赖的管理, Dart
语言提供了 pub
这个工具,并运用了 lockfile
思想去保证依赖的一致性,也值得你们学习。Flutter在不断成长,它的生态也在创建,这离不开开源社区的努力,当你发现想要的功能没有现成的开源库,不妨本身去写一写。
下一篇,咱们来说讲Flutter插件编写必知必会。
本文版权属于再惠研发团队,欢迎转载,转载请保留出处。@akindone