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