W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
第二章中已經(jīng)講過(guò)如何使用 Package(包),我們知道通過(guò) package 可以創(chuàng)建共享的模塊化代碼,本節(jié)將重點(diǎn)講一下如何開(kāi)發(fā)并發(fā)布我們自己的 Package。一個(gè)最小的 Package 包括:
pubspec.yaml
文件:聲明了 Package 的名稱(chēng)、版本、作者等的元數(shù)據(jù)文件。lib
文件夾:包括包中公開(kāi)的(public)代碼,最少應(yīng)有一個(gè)<package-name>.dart
文件Flutter Packages 分為兩類(lèi):
fluro
(opens new window)包。battery
(opens new window)插件包。注意,雖然 Flutter 的 Dart 運(yùn)行時(shí)和 Dart VM 運(yùn)行時(shí)不是完全相同,但是如果 Package 中沒(méi)有涉及這些存在差異的部分,那么這樣的包可以同時(shí)支持 Flutter 和 Dart VM,如 Dart http 網(wǎng)絡(luò)庫(kù)dio (opens new window)。
下面我將帶領(lǐng)讀者一步步來(lái)開(kāi)發(fā)一個(gè) Dart Package。
您可以通過(guò) Android Studio:File>New>New Flutter Project 來(lái)創(chuàng)建一個(gè) Package 工程,如圖12-1所示:
您也可以通過(guò)使用--template=package
來(lái)執(zhí)行 flutter create
命令來(lái)創(chuàng)建:
flutter create --template=package hello
這將在hello/
文件夾下創(chuàng)建一個(gè)具有以下專(zhuān)用內(nèi)容的 package 工程:
lib/hello.dart
:Package 的 Dart 代碼test/hello_test.dart
:Package 的單元測(cè)試代碼。
對(duì)于純 Dart 包,只需在主lib/<package name>.dart
文件內(nèi)或lib
目錄中的文件中添加功能即可 。要測(cè)試軟件包,請(qǐng)?jiān)?code>test目錄中添加unit tests (opens new window)。下面我們看看如何組織 Package 包的代碼,我們以 shelf Package 為例,它的目錄結(jié)構(gòu)如圖12-2所示:
在 lib 根目錄下的“shelf.dart”中,導(dǎo)出了多個(gè)“l(fā)ib/src”目錄下的 dart 文件:
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';
而 Package 中主要的功能的源碼都在 src 目錄下。shelf Package 也導(dǎo)出了一個(gè)迷你庫(kù): shelf_io,它主要是處理 HttpRequest 的。
當(dāng)需要使用這個(gè) Package 時(shí),我們可以通過(guò)"package:"指令來(lái)指定包的入口文件:
import 'package:utilities/utilities.dart';
同一個(gè)包中的源碼文件之間也可以使用相對(duì)路徑來(lái)導(dǎo)入。
可以使用 dartdoc (opens new window)工具來(lái)為 Package 生成文檔,開(kāi)發(fā)者需要做的就是遵守文檔注釋語(yǔ)法在代碼中添加文檔注釋?zhuān)詈笫褂?dartdoc 可以直接生成 API 文檔(一個(gè)靜態(tài)網(wǎng)站)。文檔注釋是使用三斜線(xiàn)"///"開(kāi)始,如:
/// The event handler responsible for updating the badge in the UI.
void updateBadge() {
...
}
詳細(xì)的文檔語(yǔ)法請(qǐng)參考dartdoc (opens new window)。
如果我們正在開(kāi)發(fā)一個(gè)hello
包,它依賴(lài)于另一個(gè)包,則需要將該依賴(lài)包添加到pubspec.yaml
文件的dependencies
部分。 下面的代碼使url_launcher
插件的 API 在hello
包中是可用的:
在 hello/pubspec.yaml
中:
dependencies:
url_launcher: ^0.4.2
現(xiàn)在可以在hello
中import 'package:url_launcher/url_launcher.dart'
然后調(diào)用 launch()
方法了。
這與在Flutter應(yīng)用程序或任何其他 Dart 項(xiàng)目中引用軟件包沒(méi)有什么不同。
但是,如果hello
碰巧是一個(gè)插件包,其平臺(tái)特定的代碼需要訪(fǎng)問(wèn)url_launcher
公開(kāi)的特定于平臺(tái)的 API,那么我們還需要為特定于平臺(tái)的構(gòu)建文件添加合適的依賴(lài)聲明,如下所示。
Android
在 hello/android/build.gradle
:
android {
// lines skipped
dependencies {
provided rootProject.findProject(":url_launcher")
}
}
您現(xiàn)在可以在hello/android/src
源碼中import io.flutter.plugins.urllauncher.UrlLauncherPlugin
訪(fǎng)問(wèn)UrlLauncherPlugin
類(lèi)。
iOS
在hello/ios/hello.podspec
:
Pod::Spec.new do |s|
# lines skipped
s.dependency 'url_launcher'
您現(xiàn)在可以在hello/ios/Classes
源碼中 #import "UrlLauncherPlugin.h"
然后訪(fǎng)問(wèn) UrlLauncherPlugin
類(lèi)。
假設(shè)我們想在我們的hello
包中使用some_package
和other_package
,并且這兩個(gè)包都依賴(lài)url_launcher
,但是依賴(lài)的是url_launcher
的不同的版本。 那我們就有潛在的沖突。避免這種情況的最好方法是在指定依賴(lài)關(guān)系時(shí),程序包作者使用版本范圍 (opens new window)而不是特定版本。
dependencies:
url_launcher: ^0.4.2 # 這樣會(huì)較好, 任何0.4.x(x >= 2)都可.
image_picker: '0.1.1' # 不是很好,只有0.1.1版本.
如果some_package
聲明了上面的依賴(lài)關(guān)系,other_package
聲明了url_launcher
版本像’0.4.5’或’^0.4.0’,pub將能夠自動(dòng)解決問(wèn)題。
即使some_package
和other_package
聲明了不兼容的url_launcher
版本,它仍然可能會(huì)和url_launcher
以兼容的方式正常工作。 你可以通過(guò)向hello
包的pubspec.yaml
文件中添加依賴(lài)性覆蓋聲明來(lái)處理沖突,從而強(qiáng)制使用特定版本:
強(qiáng)制使用 0.4.3
版本的url_launcher
,在 hello/pubspec.yaml
中:
dependencies:
some_package:
other_package:
dependency_overrides:
url_launcher: '0.4.3'
如果沖突的依賴(lài)不是一個(gè)包,而是一個(gè)特定于 Android 的庫(kù),比如guava
,那么必須將依賴(lài)重寫(xiě)聲明添加到 Gradle 構(gòu)建邏輯中。
強(qiáng)制使用23.0
版本的guava
庫(kù),在hello/android/build.gradle
中:
configurations.all {
resolutionStrategy {
force 'com.google.guava:guava:23.0-android'
}
}
Cocoapods 目前不提供依賴(lài)覆蓋功能。
一旦實(shí)現(xiàn)了一個(gè)包,我們可以在Pub (opens new window)上發(fā)布它 ,這樣其他開(kāi)發(fā)者就可以輕松使用它。
在發(fā)布之前,檢查pubspec.yaml
、README.md
以及CHANGELOG.md
文件,以確保其內(nèi)容的完整性和正確性。然后,運(yùn)行 dry-run 命令以查看是否都準(zhǔn)備OK了:
flutter packages pub publish --dry-run
驗(yàn)證無(wú)誤后,我們就可以運(yùn)行發(fā)布命令了:
flutter packages pub publish
如果你遇到包發(fā)布失敗的情況,先檢查是否因?yàn)楸娝苤木W(wǎng)絡(luò)原因,如果是網(wǎng)絡(luò)問(wèn)題,可以使用 VPN,這里需要注意的是一些代理只會(huì)代理部分 APP 的網(wǎng)絡(luò)請(qǐng)求,如瀏覽器的,它們可能并不能代理 dart 的網(wǎng)絡(luò)請(qǐng)求,所以在這種情況下,即使開(kāi)了代理也依然無(wú)法連接到 Pub,因此,在發(fā)布 Pub 包時(shí)使用全局代理或全局 VPN 會(huì)保險(xiǎn)些。如果網(wǎng)絡(luò)沒(méi)有問(wèn)題,以管理員權(quán)限(sudo)運(yùn)行發(fā)布命令重試。
很多時(shí)候開(kāi)啟全局代理也不會(huì)讓 terminal 中的流量打代理服務(wù)器走,以 socks5 為例,應(yīng)該在終端下輸入以下指令:
export all_proxy=socks5://127.0.0.1:1080
此時(shí)終端中的 http 和 https 流量會(huì)打代理服務(wù)器走,可以通過(guò)
curl -i https://ip.cn
指令查看代理設(shè)置是否成功。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: