大家好,我是 17。
Flutter 打包的文章一共有兩篇
- Flutter Android 打包保姆式全流程 2023 版
- Flutter IOS 新建打包發(fā)布全流程 2023 版
本篇介紹 Android 的打包全流程。
為什么要寫這篇文章呢?對于一沒有 android 開發(fā)經(jīng)驗,從未有過打包經(jīng)歷的新人來說,要想成功打包,是很困難的。因為受到的阻礙太多,是完全陌生的領(lǐng)域,幾乎是寸步難行。如果有老人帶還行,如果沒有,那就只能自己四處找人或搜索資料求指導(dǎo)了。可惜的是,網(wǎng)上的文章不是過時了,就是不全,或是講的不夠明白,要幾經(jīng)坎坷才能成功。但是只要成功打包一次,回頭再看,其實也是滿簡單的嘛,所缺少的只是一份完整的資料而已。
為了能讓首次打包 android 的小伙伴不必再經(jīng)歷四處碰壁的磨難,17 決定寫這篇文章,從此 android 打包不求人。雖然已經(jīng)很詳細,但還是不可能面面俱到,保證能發(fā)包。有的地方只是點到為止。
操作系統(tǒng) Mac OS
- Flutter 版本 3.7.5
- android SDK 33
在打包之前,首先檢查 pubspec.yaml 中的依賴,刪除沒有用到的依賴,減少包的大小。如果需要網(wǎng)絡(luò)權(quán)限,需要在 android/app/src/main/AndroidManifest.xml 中添加網(wǎng)絡(luò)權(quán)限申請。
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
權(quán)限 INTERNET 允許網(wǎng)絡(luò)連接。
權(quán)限 ACCESS_NETWORK_STATE 允許程序獲取網(wǎng)絡(luò)信息狀態(tài)。如果用不到,這條權(quán)限可以不申請。
如果要用 http ,但是需要在 AndroidManifest.xml 的 applictation 加如下配置 android:usesCleartextTraffic="true"
下面詳細說下打包的主要過程。
設(shè)置應(yīng)用 ID 和包名
在建項目的時候可以直接設(shè)置應(yīng)用 ID 和包名。
–org 指定 applicationId 的前綴,默認為 "com.example”,我們指定為 com.iam17,項目名為 app17。
flutter create --org=com.iam17 app17
創(chuàng)建成功后,項目的應(yīng)用 ID(applicationId) 是 com.iam17.app17。包名(package) 也是 com.iam17.app17
默認情況下,項目的軟件包名稱與應(yīng)用 ID 是一樣的。
如果開始無法確定 org,到發(fā)版的時候才確定怎么辦。 對于新手來說,與其做修改,不如直接新建項目,把 lib 下面的文件 copy 過來,并對 android 下面的內(nèi)容做相應(yīng)修改,這樣肯定效率更高,也不容易出錯。
應(yīng)用 ID 和包名的區(qū)別
你一定會很奇怪,既然他們兩個一樣,為什么不用一個?
他們兩個一個主外,一個主內(nèi)。
應(yīng)用 ID 主外,是 android app 的身份證,全球唯一。一般是把域名倒過來,加上你的 app 的名字。
包名主內(nèi),包名是 app 代碼需要的。
-
它將此名稱用作應(yīng)用生成的
R.java
類的命名空間。示例:對于上面創(chuàng)建的項目,
R
類將為com.iam17.app17.R
。 -
它會使用此名稱解析清單文件中聲明的任何相關(guān)類名。
一個應(yīng)用使用一個包名,但可以使用不同的應(yīng)用 ID 發(fā)布為多個不同的應(yīng)用,在應(yīng)用市場上可以共存,這就是為什么要把應(yīng)用 ID 和 包名分開的原因。
應(yīng)用 ID 的位置
應(yīng)用 ID 在gradle在 android/app/build.gradle 的 defaultConfig 中設(shè)置,新版本的 flutter 在新建項目的時候已經(jīng)自動設(shè)置好了。
android {
defaultConfig {
applicationId = "com.iam17.app17"
...
如果沒有設(shè)置 applicationId,為了與以前的 SDK 工具兼容,構(gòu)建工具會將 AndroidManifest.xml
文件中的包名稱用作應(yīng)用 ID。在這種情況下,重構(gòu)您的軟件包名稱也會更改您的應(yīng)用 ID。
包名的位置
AndroidManifest.xml 文件中的 package 屬性就是包名。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iam17.app17"
...
>
package 輕易不要修改,修改起來比較麻煩。不是光修改這一個地方就完事了,還要調(diào)整目錄結(jié)構(gòu),修改文件中的代碼。
包名和應(yīng)用 ID 的位置了解一下即可,一般不需要我們手動去修改。
修改版本號
打開 pubspec.yaml 找到 version: 1.0.0+1
。
可能有的小伙伴對版本號不知道為什么用 3 位,我來解釋一下。
一般來講大部分的軟件版本號 分 3 段,比如 A.B.C
A 表示大版本號,一般當軟件整體重寫,或出現(xiàn)不向后兼容的改變時,增加A。
一般來說,第一版發(fā)布的時候是 1.0.0。
B 表示功能更新,出現(xiàn)新功能時增加B。
比如原來沒有點贊功能,增加點贊功能的版本可以是 1.1.0。
有的時候,軟件還在快速迭代中,很容易出現(xiàn)向前不能兼容的情況,這個時候,也可以直接用 B 來代替 A 的作用。比如發(fā)第一版的時候,用 0.1.0。等穩(wěn)定后再發(fā) 1.0.0 版本。一般來說 A 是不應(yīng)該經(jīng)常變動的。
C 表示小修改,如修復(fù)bug,只要有修改就增加C
C 的更新可以不經(jīng)測試,直接更新。如果功能要修改,也必須要兼容以前的版本,也就是說接口是不能修改的,只能修改邏輯實現(xiàn)。
還有后面的 +1 是怎么回事? +號可以看做是分隔符。1 是累計版本,從 1 開始,只能增加,不能減小,并且,每次發(fā)版必須增加。這個版本號是給內(nèi)部用的。比如蘋果商店,android 平臺都用這個版本號來判斷軟件的新舊。3 位版本號是給用戶看的。3 位版本號包含軟件更新的信息,讓人一看就知道是重大更新,還是功能增加,還是 bug 修復(fù)。
消除 build.gradle 中的錯誤提示
打開 android/app/build.gradle 后,你可能會發(fā)現(xiàn)有一個錯誤提示:unable to resolve class GradleException。

新建的項目可能也有這個問題,雖然不影響編譯,但是有這個錯誤在總是心里不舒服。我們可以把 GradleException 換成 FileNotFoundException 錯誤提示就消失了。
設(shè)置 sdk 版本
在 android 下面有三個版本相關(guān)的配置 compileSdkVersion,minSdkVersion,targetSdkVersion,需要我們關(guān)注一下。
- compileSdkVersion 告訴 gradle 用哪個 Android SDK 版本編譯你的應(yīng)用。compileSdkVersion 決定了你可以用哪個版本的 api。比如你的 compileSdkVersion 是 31,如果你在代碼中用了 33 的 api,編譯會報錯。一般我們都把 compileSdkVersion 設(shè)置為最高版本。
- minSdkVersion 是應(yīng)用可以運行的最低版本要求。也就是你要向下兼容哪些版本。根據(jù) app 的用戶特點,盡量設(shè)得高一些,否則很多插件不能用。
- targetSdkVersion 告訴 android 系統(tǒng),app 要在哪個版本運行。android 的 api 在不同版本之間,雖然接口沒有變化,但內(nèi)部的行為可能發(fā)生了變化。當你指定了 targetSdkVersion 后,一定要在這個版本做完整的測試。新開項目 targetSdkVersion 應(yīng)該和 compileSdkVersion 保持一致。支持新近的 API 級別有助于讓您的應(yīng)用利用平臺的最新功能,為用戶提供愉悅的體驗。
說了半天,你可能最想知道,到底寫什么?既然是新手第一次發(fā)包,那項目應(yīng)該是新的。推薦這樣設(shè)置。
compileSdkVersion 33
minSdkVersion 23
targetSdkVersion 33
33 是當前 Android SDK 最新版本,如果你本機沒有安裝 SDK 33,需要先安裝。
具體要如何修改呢?兩個方案
- 修改 flutter安裝目錄/packages/flutter_tools/gradle/flutter.gradle
class FlutterExtension {
static int compileSdkVersion = 33
static int minSdkVersion = 16
static int targetSdkVersion = 33
...
默認的 minSdkVersion 竟然是 16,一定得修改,這個確實太低了。注意,在這里修改會影響到所有項目。
- 修改項目中的 android/app/build.gradle
比如修改 minSdkVersion,把變量換成常就行
defaultConfig {
applicationId "com.iam17.app17"
minSdkVersion flutter.minSdkVersion
...
修改為
defaultConfig {
applicationId "com.iam17.app17"
minSdkVersion 23
...
另外兩個已經(jīng)是最新了,就不用修改了。如果需要修改,修改為 33 就行。雖然有兩種方案,但 17 推薦第 2 種,直接在項目中修改。
添加 launcher icon
launcher icon 就是下面圖中的這些小方塊。

如果要手動設(shè)置 launcher icon 還是很麻煩的。幸運的是,這個問題被一個叫 flutter_launcher_icons 的插件解決了。所以原來那個超級麻煩的問題現(xiàn)在就轉(zhuǎn)變?yōu)閷W(xué)會使用這個插件就行了。
- 安裝 flutter_launcher_icons 插件
flutter pub add dev:flutter_launcher_icons
注意前面的 dev:
表示作為開發(fā)期間的依賴,flutter_launcher_icons 會出現(xiàn)在 dev_dependencies 下面。出現(xiàn)在這里的好處是等發(fā)版的時候 flutter_launcher_icons 不會被包括里 apk 中。
-
準備一張 1024x1024 的圖片。如果你手邊沒有合適的,17 親手畫了一張,可以 點擊這里,打開原圖,右鍵另存下載。在根目錄下建一個文件夾 images,把圖片命名為 icon1024.png 放入 images 文件夾中。
-
添加配置信息,打開 pubspec.yaml
flutter_icons:
image_path: "images/icon1024.png"
android: true
ios: true
- 執(zhí)行創(chuàng)建命令
flutter pub run flutter_launcher_icons:main
- 檢查生成的圖片
打開 android/app/src/main/res/drawable 文件夾查看已經(jīng)生成好的圖片,發(fā)現(xiàn)所有圖片都已經(jīng)自動生成好了。
為 ios 生成的圖片路徑 在 ios/Runner/Assets.xcassets/AppIcon.appiconset
注意事項
- Format: 32-bit PNG
- icon 大小必須是 1024x1024
- 確保在 40px 大小時也能清晰可見,這是 icon 最小的尺寸。
- icon 不能大于 1024KB
- icon 不能是透明的。
- 必須是正方形,不能有圓角。
icon 的邊可能會被切掉,因為 Icon 最后展示的可能不是正方形,所以一般邊上需要留白。
設(shè)置 App Name
App Name 就是 App 安裝成功后在圖標下面顯示的名字。
打開 flutter根目錄/android/app/src/main/AndroidManifest.xml,
<application
android:label="App Name" > //在這修改 Android App Name。
設(shè)置 Splash Screen
雖然可以手動設(shè)置,但對于新手來說,用 flutter_native_splash 這個插件會更方便一些。
安裝
flutter pub add flutter_native_splash
在項目根目錄下找到文件夾 images,把 splash.png 放入其中。
在 pubspec.yaml 的末尾加上配置
flutter_native_splash:
color: "#42a5f5"
image: images/splash.png
執(zhí)行創(chuàng)建命令
flutter pub run flutter_native_splash:create
運行,第一時間就會看到啟動畫面了。splash.png 會居中顯示。
說明
- splash.png 要準備 4x 的。插件會自動為我們生成小分辨率的
- 每次修改配置都得重新執(zhí)行
flutter pub run flutter_native_splash:create
- 不光是配置了 android 的啟動頁面,ios,web 的也一起生成好了。
有一個小福利。默認情況下當 flutter 開始繪制的時候, Splash Screen 就自動消失了。但這個時候,首屏的數(shù)據(jù)可能還沒有準備好,還無法顯示畫面,我們可能還得準備一個 loading 的畫面。現(xiàn)在你可以繼續(xù)顯示 Splash Screen,直到首屏數(shù)據(jù)準備完畢。
代碼很好寫的。我們用 Timer 來模擬數(shù)據(jù)準備。
void main() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
runApp(const MyApp());
Timer(Duration(seconds: 10), () {
FlutterNativeSplash.remove();
});
}
如果你哪天想自己配置可以恢復(fù)到默認狀態(tài)
flutter pub run flutter_native_splash:remove
現(xiàn)在的啟動頁面只有一張圖片,但一般在啟動頁面的底部還會有一個 品牌 logo。你可以把 logo 合并在主圖上,但這樣就無法保證 logo 出現(xiàn)在底部的位置。所以 logo 需要單獨用一張圖片。
在 pubspec.yaml 中增加 branding 的配置。
flutter_native_splash:
color: "#42a5f5"
image: images/splash.png
branding: images/logo.png
重新執(zhí)行 flutter pub run flutter_native_splash:create
就可以看到 logo 了。如果你覺得 logo 太靠下了,可以把 logo 的圖片下面留點空白。
簽名
要想把 app 發(fā)布到商店,必須要對 app 進行簽名。簽名有兩種方式,命令式,和交互式。命令式對新手不大友好,我用交互的方式來說明。
在 IDE 中運行或調(diào)試項目時,AS 會自動使用 Android SDK 工具生成的調(diào)試證書為我們的應(yīng)用簽名,路徑為 $HOME/.android/debug.keystore
,但是應(yīng)用商店可不接受使用調(diào)試證書發(fā)布的應(yīng)用簽名。為了給應(yīng)用簽名,需要先創(chuàng)建密鑰。
創(chuàng)建密鑰
打開 Android Studio ,找到 Build 菜單下面的 Generated Signed Bundle/APK

會彈出下面這個對話框

有兩個選項
- Android App Bundle 如果你要上傳到 google 商店,選這個。你暫可以理解為 這是 APK 優(yōu)化方案,可惜不是所有的商店都支持。
- APK 就是傳統(tǒng)的打包,為了兼容所有商痁,我們選這個就好了。
接下來又會彈窗

Key store path: 是你要將 key 保存在哪里,可以先找個地方放,后面可以 copy 到其它地方。應(yīng)在位置路徑末尾添加一個擴展名為 .jks
的文件名。點擊 Create new 新建一個,比如文件名可以叫 key17.jks。
key store passowrd: 為您的密鑰庫創(chuàng)建并確認一個安全的密碼。設(shè)置好了必須要記住。
- Alias:為您的密鑰輸入一個標識名。 比如可以叫 key17。
- Password:為您的密鑰創(chuàng)建并確認一個安全的密碼。它應(yīng)該與密鑰庫密碼相同。具體原因就不用管了,把它設(shè)成和 key store passowrd 一樣就沒問題了。密碼要求至少 6 位。
- Validity (years) :以年為單位設(shè)置密鑰的有效時長。密鑰的有效期應(yīng)至少為 25 年,以便您可以在應(yīng)用的整個生命期內(nèi)使用同一密鑰為應(yīng)用更新簽名。我直接寫 100 年,讓它沒有過期的可能。
Certificate: 為證書輸入一些關(guān)于您本人的信息。此信息不會顯示在應(yīng)用中,但會作為 APK 的一部分包含在您的證書中。只有第一項是必須填的,其它的空著就行。當然了,如果寫全了更好。


選中 release,點下面的按鈕 create。然后簽名文件就生成好了。
使用密鑰為應(yīng)用自動簽名
先把創(chuàng)建好的 key 文件 copy 到 android 目錄下。
建立 keystore.properties 文件
在 android 文件夾下建立名為 keystore.properties 文件,不叫這個名也可以,但一般都這么叫,沒有特別的原因,還是用這個名字為好。在文件里放如下內(nèi)容
storePassword=123456
keyPassword=123456
keyAlias=key17
storeFile=../key17.jks
注意:這里的 keyAlias 要和前面設(shè)置的 key alias 保持一致,否則找不到 key。密碼當然也要一樣。
添加 gradle 配置
在 build.gradle 文件中,按如下方式加載 keystore.properties 文件(必須在 android 代碼塊前面)
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
...
}
輸入存儲在 keystoreProperties
對象中的簽名信息
android {
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
...
}
...
多渠道統(tǒng)計
apk 會發(fā)到不同的商店,你可能想知道哪個商店的下載量最大。這就需要渠道統(tǒng)計,這個功能要用到 dart 參數(shù)。
--dart-define
來指定不同的 dart 參數(shù),比如
flutter build apk --dart-define channel=huawei
在 dart 代碼里可以通過 String.fromEnvironment
獲取到對應(yīng)的自定義配置參數(shù)。
const channel = String.fromEnvironment('channel');
dart 代碼拿到 channel 后就可以發(fā)統(tǒng)計數(shù)據(jù)出來。
發(fā)布優(yōu)化
啟用縮減、混淆處理和優(yōu)化功能,
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
...
}
發(fā)布和安裝
現(xiàn)在執(zhí)行發(fā)布命令
flutter build apk --release
--release
可以省略,是默認值。
不出意外的話,build 成功可以看到類似如下信息
Built build/app/outputs/flutter-apk/app-release.apk (37.6MB)
apk 已經(jīng)生成了,怎么裝到手機上呢?三種方法。
- 通過網(wǎng)絡(luò)把 apk 發(fā)到手機上。比如有的包就是通過一個 http 鏈接發(fā)布的,下載后可以直接安裝。
- 通過 adb 命令安裝
adb install build/app/outputs/flutter-apk/app-release.apk
- 通過
flutter install
命令安裝
優(yōu)化
雖然做為新手,能打包成功就已經(jīng)滿心歡喜了,但還可以做的更好。
apk 大小優(yōu)化
不同的 Android 設(shè)備使用不同的 CPU,而不同的 CPU 支持不同的指令集。CPU 與指令集的每種組合都有專屬的應(yīng)用二進制接口 (ABI)。ABI 目前有兩大類 arm 和 x86。arm 是當前手機的主流,x86 出現(xiàn)在模擬器上。flutter 默認支持 arm 和 x86 兩種 ABI。我們用 android studio 查看一下。把剛才生成的 apk 直接拖到 android studio 上就行。查看 lib 文件夾,發(fā)現(xiàn) flutter 為我們生成了三種 ABI 的文件。

一種手機只用一種 ABI,所以把它們分別打包會更好些,體積會大大減小。只需要加一個參數(shù)就好 。
flutter build apk --split-per-abi
再看輸出目錄,原來的一個 apk 包現(xiàn)在分成三個了,每個只有原來 apk 1/3 大小。
ABI 的更多信息見 這里
到此,基本的打包流程就講完了,可以發(fā)布了。恭喜你,完成了從 0 到 1 的跨越!
如果你的產(chǎn)品只發(fā)布為一個版本,下面的內(nèi)容可以先跳過。雖然有開發(fā)環(huán)境,測試環(huán)境,也需要打不同的包,因為差異不大,可以用簡單的辦法解決。比如用 --dart-define
設(shè)置變量。
用 applicationIdSuffix 為開發(fā)版設(shè)置不同的 applicationId。
buildTypes{
...
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
多版本打包
可能你的產(chǎn)品還需要根據(jù)不同的用戶出不同的版本,比如免費版本,收費版。
多版本要面臨的問題主要有三個
- 如何讓多版本共存。
- 如何做個性化設(shè)置
- 優(yōu)化打包。你可以在所有版本中把所有的功能都加上,簡單的用開啟關(guān)閉來控制。但這樣會導(dǎo)致 apk 過大,也不大安全。
如果都手動配置,學(xué)習(xí)成本有點高,對于新手來說,可以我們可以用 flutter_flavorizr 這個插件,幫我們處理好許多事情,讓我們有一個好的起點。
安裝
flutter pub add dev:flutter_flavorizr
如果你這樣執(zhí)行安裝命令的是話,會報錯,原因是和前面的插件 flutter_launcher_icons,flutter_native_splash 的依賴沖突。解決的方法是把所有沖突的插件的 版本都改成 any,執(zhí)行 flutter pub get
讓 flutter 自己去處理沖突的問題。等安裝成功后,再到 pubspec.lock 中找到對應(yīng)的版本寫入 pubspec.yaml 中。
配置
在 pubspec.yaml 的末尾加上如下配置
、
flavorizr:
flavors:
apple:
app:
name: "Apple App"
android:
applicationId: "com.example.apple"
ios:
bundleId: "com.example.apple"
banana:
app:
name: "Banana App"
android:
applicationId: "com.example.banana"
ios:
bundleId: "com.example.banana"
flavors 可以理解為多版本發(fā)布。這個配置中有兩個版本發(fā)布配置,apple 和 banner。
name 指定 App Name 為 apple App,Banana App,App Name 就是 App 安裝成功后在圖標下面顯示的名字。
applicationId 是 app 的身份證。這里我們看到 applicationId 是不同的,代表兩個完全不同的 app,但包名是同一個。從這個實例中我們可以更加清楚的看到 applicationId 和 package 是獨立的兩個設(shè)置,不能混為一談。
執(zhí)行命令
flutter pub run flutter_flavorizr
等命令執(zhí)行完成,發(fā)現(xiàn)插件為我們做了很多事情。
自動完成 flavor 配置
build.grade 中增加了 flavor 的配置
// ----- BEGIN flavorDimensions (autogenerated by flutter_flavorizr) -----
flavorDimensions "flavor-type"
productFlavors {
apple {
dimension "flavor-type"
applicationId "com.example.apple"
resValue "string", "app_name", "Apple App"
}
banana {
dimension "flavor-type"
applicationId "com.example.banana"
resValue "string", "app_name", "Banana App"
}
}
// ----- END flavorDimensions (autogenerated by flutter_flavorizr) -----
注意:BEGIN ,END 這兩行注釋不要做修改,也不能刪除,否則插件無法維護這里面的配置了。
自動添加資源文件
在 android/app/src 下多了兩個文件夾 banner,apple 里面有啟動 icon。
自動增加不同版本的入口文件
lib 下面增加了四個文件:main_apple.dart,main_banana.dart,app.dart,flavios.dart
原來的 main.dart 還是在的,我們執(zhí)行 flutter run 還是會啟動 main.dart,就像沒有執(zhí)行過 flutter pub run flutter_flavorizr
一樣。
flavor 打包
為了能進行 flavor 打包,可以這樣執(zhí)行命令
flutter run --flavor apple -t lib/main_apple.dart
你會發(fā)現(xiàn),這次啟動入口是 main_apple.dart,啟動圖標也換了。這次會安裝一個新的 app,和原來 main.dart 生成的 app 共存。
我們把 banner app 也裝一下。
flutter run --flavor banana -t lib/main_banana.dart
這次也會新安裝一個 app,和前面的 apple app,main app 并存。
main app 的 applicationId 是 com.iam17.app17,apple app 的 applicationId 是 com.example.apple ,它們可以完全不一樣,applicationId 就是一個身份標識,只要全球唯一就行。我們做的產(chǎn)品的時候,不可能這樣隨意設(shè)置 applicationId,一般前面的不變,只修改最后的名字。比如可以這樣設(shè)置
com.iam17.app17.free
com.iam17.app17.pro
com.iam17.app17.test
com.iam17.app17.debug
設(shè)置 api url
不同版本的 api 的地址可能是不同的。我們可以打開 flaors.dart,仿照 title 增加一個apiUrl,在需要的地方,用 F.apiUrl
獲取地址。
static String get apiUrl {
switch (appFlavor) {
case Flavor.APPLE:
return 'http://apple/api';
case Flavor.BANANA:
return 'http://banana/api';
default:
throw UnimplementedError();
}
}
flaors.dart 默認是受 插件管理的,如果你再次執(zhí)行 flutter pub run flutter_flavorizr
,flaors.dart 的內(nèi)容會被重置。為了避免內(nèi)容被重置,下次再執(zhí)行命令的時候,需要挑選 processor 執(zhí)行。
flutter pub run flutter_flavorizr -p <processor_1>,<processor_2>
vscode 配置 launch.json
為了啟用不同的 flavor,需要在執(zhí)行命令的時候加個 flavor 參數(shù) 和 target(-t) 參數(shù),每次寫這么長的命令很不方便。我們可以在 vscode 中增加 lauch.json 把命令記錄下來。下次運行的時候,只要點個按鈕就可以了。
增加 launch.json
如果你的項目里沒有 lauch.json 點紅框那個圖標,就會有添加提示,點擊 create a lauch.json file,就會自動為你添加一個。

替換成下面的內(nèi)容
{
"version": "0.2.0",
"configurations": [
{
"name": "apple",
"program": "./lib/main_apple.dart",
"request": "launch",
"type": "dart",
"args": ["--flavor","apple"]
},
{
"name": "banana",
"program": "./lib/main_banana.dart",
"request": "launch",
"type": "dart",
"args": ["--flavor","banana"]
}
]
}
同樣點左面那個 run and debug 圖標,這時會出現(xiàn)我們剛配置好的兩從此啟動,apple和 banana。apple 前面打勾,表示默認,直接按 F5 會用啟動 apple,可以點 banana,把默認改為 banana。

為了齊整,現(xiàn)在可以把默認的 main.dart 刪除,把閃屏相關(guān)的代碼也 copy 到 main_apple.dart 中。把 launcher icon 也 copy 到 apple 下面。為了能讓大家看到執(zhí)行 launcher icon 插件的效果,main 下面的 icon 就不刪除 了。
可能有些地方講的還不是很清楚,17 特地準備了 android flavor 項目示例,完整代碼 在這里。
本文用了三個插件來解決三個不方便處理的問題,以便降低打包難度,快速上手。在使用插件的時候,應(yīng)該了解插件做了什么,最后應(yīng)該能做到手動也可以處理。
本文到這里就結(jié)束了,希望小伙伴們都能順利 build 成功!如果哪里還有疑問,歡迎留言。文章來源:http://www.zghlxwxcb.cn/news/detail-404053.html
番外
這篇文章要寫好很不容易,修改了多少次都不記得了。涉及到的內(nèi)容非常多,我想把應(yīng)提到的點都提到,但又不至于過于冗長。我想讓學(xué)習(xí)曲線變得平緩,把多版本打包做為可選內(nèi)容放在了最后。為了能先看到效果,先講了基本流程,保證能打出包來。17 寫的很辛苦,周末又是兩天沒有出門。本來想分兩篇文章發(fā)的,因為內(nèi)容有點長,但考慮到是全流程,還是一起發(fā)了。 這一次 17 又是耗盡所有的力氣,直到周一早上才最后定稿,小伙伴快點給 17 在評論區(qū)評論加油吧。文章來源地址http://www.zghlxwxcb.cn/news/detail-404053.html
到了這里,關(guān)于Flutter Android 打包保姆式全流程 2023 版的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!