0
1

More than 3 years have passed since last update.

Flutter Androidでflavorを指定したらエントリポイントのmain.dartが自動設定されるようにしたい

Last updated at Posted at 2021-08-11

背景

Flutter で作ったアプリを flutter run や build する際は、以下のように --flavor オプションでビルドフレーバーを、さらに -t オプションを使ってエントリポイントの dart ファイルを指定します。

flutter run --flavor dev -t lib/main_dev.dart

Android Studio でビルド/実行するときはプロジェクトの Configuration でフレーバー名とエントリーポイントの dart ファイルを指定します。

Screen Shot 2021-08-11 at 14.39.18.png

しかし、冗長です。単に、フレーバー hoge を設定したら自動で main_hoge.dart が選ばれてくれないだろうか...。
(※iOSではスキーム毎に.xcconfigファイルを作ってFLUTTER_TARGETを指定すれば、自動化できます)

やってみたら、一応できましたので、やリ方をメモしておきます。

ただ、実装はかなりトリッキーな方法なので、あまりオススメではありません。
flutter run や build 以外の方法、たとえば gradle のタスクを直接実行するなどすると、正しく動かないかもしれません。

やり方

Flutter 2.2.3, gradle 6.7を前提とします。

./android/app/build.gradleflutter.gradle を読み込んでいる行の後に、以下のコードを追加すると、 main.dart の代わりに main_<flavor>.dart が読み込まれるようになります。

/android/app/build.gradle
...
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
// ↑この行より後に以下を追加する

def getCurrentFlavor() {
    String tskReqStr = getGradle().getStartParameter().getTaskRequests().toString()
    def matcher = tskReqStr =~ /(assemble|bundle)(\w+)(Release|Profile|Debug)/
    if(matcher.find()) {
        return matcher.group(2).toLowerCase()
    }
    return null
}

if (project.hasProperty('target')) {
    if (project.target == null || project.target ==~ /.*main\.dart$/) {
        def flavor = getCurrentFlavor()
        project.target = "lib/main_${flavor}.dart"
    } else {
        // 外部から main.dart 以外のファイルが指定されていた場合は、
        // こちらに分岐。外部から指定されたdartファイルを優先する
    }
}

実行中のタスクの名称を無理やり読み込んで、そこからフレーバー名を抽出し、project.targetを書き換えるという、無茶苦茶な方法ですが、一応うごくようです。

フレーバー名の抽出ロジックは、assemble<Flavor><BuildType> (apk 生成時)か bundle<Flavor><BuildType> (appbundle 生成時)の Gradle タスク名を前提に書いてあるため、それ以外の名前のタスクが叩かれる場合は、適宜修正する必要があります。

補足

次のように記述すると一見、期待通り動きそうに思えますが、動きません。project.target はフレーバー毎のプロパティではないため、フレーバーの指定によらず、いちばん最後に書いた project.target が有効になってしまいます。

build.gradle
// 実際には動かない例
...
    flavorDimensions "env"
    productFlavors {
        dev {
            dimension "env"
            applicationIdSuffix ".dev"
            project.target = "lib/main_dev.dart"
        }
        stg {
            dimension "env"
            applicationIdSuffix ".stg"
            project.target = "lib/main_stg.dart"
        }
        prod {
            dimension "env"
            project.target = "lib/main_prod.dart"
        }
    }
..
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1