本文基于的 Gradle 版本為 5.6.2,Android Gradle 插件版本為 3.5.0,IDE 為 Android Studio 4.0.1,Flutter 版本為 channel stable v1.17.5
Android 開發過程中,我們習慣通過 productFlavors 來配置不同環境,比如網絡 api url
productFlavors {
// 開發環境
env_dev {
buildConfigField 'String', 'API_URL', '"http://xxx.xxx.xxx.xxx/"'
}
// 測試環境
env_test {
buildConfigField 'String', 'API_URL', '"http://xxx.xxx.xxx.xxx/"'
}
// 生產環境
env_prod {
buildConfigField 'String', 'API_URL', '"https://xxx.xxx.xxx.xxx/"'
}
}
編譯之后,會在 BuildConfig.java 中生成一個常量
// BuildConfig.java
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.xxx.xxx";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "env_dev";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0.0";
// Fields from product flavor: env_dev
public static final String API_URL = "http://xxx.xxx.xxx.xxx";
}
Flutter 代碼無法直接訪問這些常量,但是可以通過插件間接訪問。
但是現在如果運行項目的話,會出現一個錯誤信息
Exception: Gradle build failed to produce an .apk file. It's likely that this file was generated under /xxx/xxx/build, but the tool couldn't find it.
簡單分析一下,應該是點擊 Android Studio 的 Run 按鈕,調用的是 flutter run
命令,由于 build.gradle 中配置了 productFlavors,所以構建工具不知道執行哪一個,所以在控制臺執行 flutter run --flavor env_dev
就可以運行了。當然作為 IDE 黨,敲命令這么原始的方式怎么能忍,點擊 Edit Configurations...,在 Build flavor 一欄填上 env_dev,把 name 修改一下,比如就叫“開發環境”。
現在可以點擊 Run 按鈕運行了,但是
main.dart
文件只有一個,那么其他兩個環境要如何配置呢?上圖中的 Dart entrypoint 一欄中填的就是 main.dart 文件路徑,說明這個入口是可以指定的,命名也不是必須為 main.dart,所以我們把 main.dart 改名為
main_dev.dart
,再復制兩個,分別命名為 main_test.dart
和 main_prod.dart
,代表測試環境和生產環境。然后點擊 Run/Debug Configurations 對話框的加號按鈕,新建兩個新的配置,依次填好對應的信息,然后在 IDE 中直接選擇對應的環境即可調試運行。
說完了調試,再來說說打包 APK。Android 項目選擇 Build - Generate Signed Bundle / APK... 選擇 APK,下一步就會出現讓你選擇 productFlavors 的選項,選擇后點完成即可簽名打包。
但 Flutter 項目中只能選擇 Build - Flutter - Build APK 選項,還有一種方法是,打開 Flutter 項目下的 Android 項目,然后和原生項目一樣打包。這兩種方式在 main.dart 改名后都不能成功打包,前者原因也是 IDE 執行的是 flutter build apk
,構建工具既無法確定入口 main 文件是哪個,也無法確定執行哪個 productFlavor;后者就是無法確定入口文件。
由于 IDE 并沒有提供設置的地方(也許是我沒找到),所以只有通過控制臺命令或 shell 腳本來解決,例如:
# android_build.sh
# 編譯開發環境 APK
flutter build apk -t lib/main_dev.dart --flavor env_dev \
--target-platform android-arm,android-arm64 \
--obfuscate --split-debug-info=build/app/outputs/apk/env_dev/release
# 編譯測試環境 APK
flutter build apk -t lib/main_test.dart --flavor env_test \
--target-platform android-arm,android-arm64 \
--obfuscate --split-debug-info=build/app/outputs/apk/env_test/release
# 編譯生產環境 APK
flutter build apk -t lib/main_prod.dart --flavor env_prod \
--target-platform android-arm,android-arm64 \
--obfuscate --split-debug-info=build/app/outputs/apk/env_prod/release
總結一下就是在開發調試階段,可以通過 IDE 直接切換環境,而在 Release apk 的時候可以通過腳本解決。