- 介绍插件的搜索方式,三方库评估的意义和基本思路
- 介绍如何给应用添加插件,从源码角度看插件是如何注册生效的
- 介绍如何给插件指定版本和解决版本冲突问题
- 介绍依赖源的种类,如何从
pub
/git
/本地指定依赖库 - 介绍依赖的2种分类方式:直接依赖和传递依赖;常规依赖和dev依赖
- 介绍
pub
这个包管理工具获取依赖的流程和lockfile
文件的意义
目录结构
- 获取插件
- 插件的使用
- 依赖的分类
- 包管理
- 总结
获取插件
这里的 Flutter 插件,不是 IDE 中的插件,而指的是包含平台特定代码的包,用以提供 Flutter 框架所不支持的一些 Native API 的功能。比如常用的 shared_preferences , path_provider 等。
Flutter 框架为我们提供了很多 UI 层的控制和支持,但 APP 的功能并不局限在显示上,还需要依赖 Native 平台的支持,比如文件系统,摄像头等硬件调用等。所以Flutter为我们提供了一个Platform Channel
的机制,使得 Dart 代码可以与 Navtive 代码进行交互。基于Platform Channel
,开发者可以编写自己需要的 Native 功能,在 Dart 代码中统一调用。
搜索途径
随着Flutter社区的成长和壮大,Flutter Plugin 的数量和质量也在不断提高。当你在开发自己的 App 时,如果遇到依赖 Native 的功能时,不妨先考虑去社区搜索是否有现成的轮子。推荐2个平台:
pub.dartlang
针对 dart 语言的三方库平台,可以选择 Flutter 类型进行搜索,更有针对性,每个库根据 Popularity ,Health, Maintenance 进行打分,是搜索的首选。首页还列出了十几个 Top Popular 的项目,比如 shared_preferences, url_launcher, path_provider,可以说是基础必备插件。
github
以 flutter plugin
为关键字搜索。相对 pub.dartlang
,缺少针对性和评分体系(可以根据 issue
和 star
数进行评估,但相对来说没有那么直观),但库数量更多,更新更快(比如修复了 bug
不需要等它发布到 pub
上)。
不同平台的插件,依赖的写法也有不同,下文会说明。
引入前评估
搜索到自己所需功能的插件后,我们就直接拿来主义吗?对待开源三方库,我的倾向是先做多方对比,尝试阅读源码,做到心中有数后再引入。在我们团队,如果需要引入三方库,都必须提供一个说明文档,进行引入原因说明。
考量要点:
- 根据 pub score 或者 github 的 issue,star,维护情况进行评估
- 功能是否满足需求,API易用性如何
- 引入后对包大小影响对比
- 如果库比较简单,可以阅读源码,看它的实现方式是否科学规范
- 看 native 功能是用什么语言实现,是否 match 团队的技术栈,比如我司就更偏好 Kotlin/Swift
如果你发现这个库部分满足了业务需求,你可以选择改进它,或者重新造轮子。如果你觉得库维护者比较勤快和靠谱,项目的底子也不错,可以尝试 Fork
这个项目,并给它提 PR
。
对编写插件感兴趣的童鞋可以看看这个姊妹篇: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”));
…
}
…
}
- 在 App 的
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*)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 代码有效。
版本约束
版本格式:主版本号.次版本号.修订号,版本号递增规则如下:
- 主版本号:当你做了不兼容的 API 修改,
- 次版本号:当你做了向下兼容的功能性新增,
- 修订号:当你做了向下兼容的问题修正。
更详细的参考语义化版本
基本用法:
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 不支持强制版本覆盖
从不同的依赖源添加依赖
SDK
通俗讲,就是 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
Hosted
pub
dependencies:
transmogrify: ^1.4.0
自己的服务器
dependencies:
transmogrify: ^1.4.0
transmogrify:
hosted:
name: transmogrify
url: http://your-package-server.com
version: ^1.4.0
Git
API).
pub
dependencies:
transmogrify: ^1.4.0
自己的服务器
dependencies:
transmogrify: ^1.4.0
transmogrify:
hosted:
name: transmogrify
url: http://your-package-server.com
version: ^1.4.0