介紹
多渠道打包常規方式有兩種,Flavor
和 --dart-define
,後者是 Flutter1.17
新增的命令列可選引數,比Flavor
配置更簡單,非常適合用於環境配置。
執行命令:
flutter run --dart-define=DARTDEFINE_APP_ENV=debug
複製程式碼
通常不同開發環境對應不同的域名,有時候為了更直接區分不同環境,標題和 AppName 也標識區分,所以本文以標題、域名和 AppName 作為要動態更改的環境變數,開啟 --dart-define
配置之旅。
Flutter 配置
環境配置
新建一個環境配置檔案,用來獲取命令列中輸入不同的環境變數。
// 環境配置
class EnvConfig {
final String appTitle;
final String appDomain;
EnvConfig({
required this.appTitle,
required this.appDomain,
});
}
// 獲取的配置資訊
class Env {
// 獲取到當前環境
static const appEnv = String.fromEnvironment(EnvName.envKey);
// 開發環境
static final EnvConfig _debugConfig = EnvConfig(
appTitle: "debugTitle",
appDomain: "http://www.debugxxx.com",
);
// 釋出環境
static final EnvConfig _releaseConfig = EnvConfig(
appTitle: "releaseTitle",
appDomain: "http://www.releasexxx.com",
);
// 測試環境
static final EnvConfig _testConfig = EnvConfig(
appTitle: "testTitle",
appDomain: "http://www.testxxx.com",
);
static EnvConfig get envConfig => _getEnvConfig();
// 根據不同環境返回對應的環境配置
static EnvConfig _getEnvConfig() {
switch (appEnv) {
case EnvName.debug:
return _debugConfig;
case EnvName.release:
return _releaseConfig;
case EnvName.test:
return _testConfig;
default:
return _debugConfig;
}
}
}
// 宣告的環境
abstract class EnvName {
// 環境key
static const String envKey = "DART_DEFINE_APP_ENV";
// 環境value
static const String debug = "debug";
static const String release = "release";
static const String test = "test";
}
複製程式碼
在EnvName
裡宣告瞭三個環境,這是執行命令和打包命令裡要填寫的值。envKey
是對應的key
。
使用配置
在main
檔案裡使用前面配置的值,標題使用配置的標題,在頁面中顯示配置的域名:
return Scaffold(
appBar: AppBar(
title: Text(Env.envConfig.appTitle),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'配置的域名是:',
),
Text(
Env.envConfig.appDomain,
style: Theme.of(context).textTheme.headline4,
),
],
),
),
);
複製程式碼
執行
在終端輸入命令,先執行debug
環境:
flutter run --dart-define=DART_DEFINE_APP_ENV=debug
複製程式碼
注意,這裡的DART_DEFINE_APP_ENV
和debug
是和env_config
裡的對應的。
標題和域名是Env
裡配置的對應debug
的引數。
然後執行test
環境:
flutter run --dart-define=DART_DEFINE_APP_ENV=test
複製程式碼
IDE配置
命令列容易輸錯怎麼辦?那就配置 IDE 。
- 點選選單上的編輯配置
- 輸入命令:
- 新增
test
的配置:
複製了一份,命名為test
,把引數改為test
- 繼續複製一份
release
。
然後要執行哪個環境,選擇對應的配置即可。
Android 配置
不僅僅在 dart 檔案裡使用到配置資訊,原生程式碼也使用到,比如配置推送和bugly,另外測試人員為了區分環境也會要求在配置不同的應用名稱字尾,那麼就需要在原生程式碼裡修改。
在build.gradle
裡設定預設配置引數
// android/app/build.gradle
/// 設定預設配置引數
def dartDefine = [
DARTDEFINE_APP_ENV: 'debug',
]
複製程式碼
然後從dart-defines
裡獲取定義的鍵值對,新增到dartEnv
裡。
// android/app/build.gradle
/// 設定預設配置引數
def dartDefine = [
DART_DEFINE_APP_ENV: 'debug',
]
if (project.hasProperty('dart-defines')) {
dartDefine = dartDefine + project.property('dart-defines')
.split(',')
.collectEntries { entry ->
def pair = URLDecoder.decode(entry).split('=')
[(pair.first()): pair.last()]
}
}
複製程式碼
定義 resValue
,或者BuildConfig
,這裡因為要改應用名,需要引用string
資源,所以用 resValue
:
defaultConfig {
applicationId "com.example.flutter_flavors"
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
resValue "string","app_name","flutter_flavor${dartEnv.DART_DEFINE_APP_ENV}"
}
複製程式碼
在清單檔案引用:
<application
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher">
複製程式碼
每次執行不同的環境,就可以看到不同的應用名字。在程式碼裡也可以通過getString("app_name")
獲取到定義的值。
Ios 配置
右鍵專案,選擇在 xcode 裡開啟:
右鍵 Flutter 目錄選擇 new flie,選擇如下所示的型別。填入名稱 Dart
:
新增預設值:
DART_DEFINE_APP_ENV=flutter_flavor
複製程式碼
在 Debug.xcconfig 和 Release.xcconfig 裡分別新增引用:
#include "DartDefine.xcconfig"
#include "DartDefineConfig.xcconfig"
複製程式碼
第一行是引用我們建立的配置檔案,第二行是在編譯時生成的(下一步配置生成程式碼)。
在 Info 裡修改Bundle name
為我們配置的值:
編輯Schema:
這裡有兩個地方需要注意,上面要選中 Runner ,下面的輸出檔名稱要和上一步引用的一致。
到此 Ios 也配置完成。選擇 test 配置執行:
應用名變成了選擇的配置。
打包
打包命令和執行命令的字尾一樣:
flutter build apk --dart-define=DARTDEFINE_APP_ENV=release
複製程式碼
原始碼 Flutter 環境:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.0.5, on Mac OS X 10.15.6 19G2021 darwin-x64,
locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] VS Code (version 1.56.0)
[✓] Connected device (2 available)
複製程式碼