🍨
Create flavors of a Flutter app in Android
Flutterの環境分けをやってみる
公式の解説を参考に、Androidの環境分けをprod
, stg
, dev
でやってみようと思ったが、見てもさっぱりわからなかった😅
この記事を参考に設定した。ビルドするだけなので、参考にはならないかも。
Androidのflavor
設定。
android/app/build.gradle
のファイルに設定を追加する。
flavorDimensions "environment"
productFlavors {
prod {
dimension "environment"
applicationIdSuffix ""
resValue "string", "app_name", "Flutter Flavor App"
}
stg {
dimension "environment"
applicationIdSuffix ".stg"
resValue "string", "app_name", "Flutter Flavor App (Staging)"
}
dev {
dimension "environment"
applicationIdSuffix ".dev"
resValue "string", "app_name", "Flutter Flavor App (Dev)"
}
}
修正後のファイル
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader("UTF-8") { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
flutterVersionCode = "1"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0"
}
android {
namespace = "com.jboycode.flutter_flavor_app"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId = "com.jboycode.flutter_flavor_app"
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
}
flavorDimensions "environment"
productFlavors {
prod {
dimension "environment"
applicationIdSuffix ""
resValue "string", "app_name", "Flutter Flavor App"
}
stg {
dimension "environment"
applicationIdSuffix ".stg"
resValue "string", "app_name", "Flutter Flavor App (Staging)"
}
dev {
dimension "environment"
applicationIdSuffix ".dev"
resValue "string", "app_name", "Flutter Flavor App (Dev)"
}
}
buildTypes {
release {
signingConfig signingConfigs.debug
}
}
}
flutter {
source = "../.."
}
スクリーンショットだとこんな感じ
実行するときのコマンド
コマンドを実行すると、prod, stg, devごとにビルドできます。
prod:
flutter run --flavor prod
stg:
flutter run --flavor stg
dev
flutter run --flavor dev
Android Studioの設定をする
lib
の中にカウンターアプリのファイル名を変えたもので良いので用意してください。
スクリーンショット貼るのでこちらを参考にしてください。
+
ボタンを押すと新しく設定を追加できる。
同じように、prod, stgも作成する。
切り替えて、Run, Debugどちらか押してビルドすると、環境分けしたファイルを指定して実行できる。
感想
Androidは難しくないように感じました。しかし、iOSは、xcodeの設定が難しい。もう少し時間がかかりそうですね。
まだ試せていないですが、REST APIを本番用とテスト用で、URLを変更する場合は、こんな感じでやるみたいです。
lib/config/environment.dartファイルを作成
import 'package:flutter/foundation.dart';
enum Flavor { prod, stg, dev }
class Environment {
static Flavor? flavor;
static String get apiBaseUrl {
switch (flavor) {
case Flavor.prod:
return 'https://api.example.com';
case Flavor.stg:
return 'https://stg-api.example.com';
case Flavor.dev:
return 'https://dev-api.example.com';
default:
return 'https://api.example.com';
}
}
static void init() {
if (kReleaseMode) {
flavor = Flavor.prod;
} else {
const flavorName = String.fromEnvironment('FLAVOR', defaultValue: 'dev');
flavor = Flavor.values.firstWhere(
(e) => e.toString() == 'Flavor.$flavorName',
orElse: () => Flavor.dev,
);
}
print('Current flavor: $flavor');
print('API Base URL: $apiBaseUrl');
}
}
lib/main.dartファイルを修正して、アプリ起動時に環境を初期化
import 'package:flutter/material.dart';
import 'config/environment.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Environment.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Flavor App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Flavor Demo'),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key? key, required this.title}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Current Flavor: ${Environment.flavor}'),
Text('API Base URL: ${Environment.apiBaseUrl}'),
],
),
),
);
}
}
Discussion