ビルドフレーバーの使用-ソースフォルダーとbuild.gradleを正しく構造化する


166

注:ザビエルの回答の後に編集された回答

Android Studioの1つの同じアプリケーションプロジェクトに異なるビルドフレーバーを使用しようとしています。ただし、適切に機能するように構成するのに非常に時間がかかっているようです。

手順:

  1. 「Test」という名前の新しいAndroid Studioプロジェクトを作成します。
  2. build.gradle *を開き、次の行を追加しました:

    productFlavors {
    flavor1 {
        packageName 'com.android.studio.test.flavor1'
        }
    flavor2 {
        packageName 'com.android.studio.test.flavor2'
        }
    }
    
  3. Android Studioを再起動すると、[ビルドバリアント]セクションに4つのビルドバリアントが表示されます。これまでに製品のフレーバーを設定することに成功したことを意味します。**
  4. flavor1の新しいSourceフォルダーを作成しました。ただし、正しい方法で行っているかどうかはわかりません。ここに私がそれをした方法があります:

    • このプロジェクトのパッケージ名は次のとおりです。 com.foo.test
    • srcフレイバー1のフォルダーを右クリックして、実際にエクスプローラーで個々のフォルダーを作成しましたsrc/flavor1/java/com/foo/test/MainActivity.java
    • 「java」フォルダが青色になっているため、上記はうまくいきました。つまり、IDEはアクティブなソースディレクトリを認識しています。また、パッケージは自動的に作成されました。これにもかかわらず、重複するクラスが見つかったという警告が表示されます。こちらのスクリーンショットをご覧ください。
    • flavor2の場合、パッケージを手動で作成しようとしましたが、flavor2の「src」フォルダーが青く表示されていないため、右クリックするとオプションが異なり、「新しいパッケージ」を使用できません。こちらの画像をご覧ください。
    • flavor1については、青色に変わる「res」ディレクトリも作成しましたが、それにもかかわらず、別の方法を使用したい場合に備えて、AndroidリソースファイルまたはAndoridリソースディレクトリを作成する機能はありません。さまざまなフレーバーのリソース。

私は何か間違ったことをしていますか?それとも何か不足していますか?さらに情報が必要な場合はお知らせください。

*私のプロジェクトには2つの build.gradleファイルがあるようです。1つはプロジェクトフォルダー(\ GradleTest)のルートにあり、これは空です。2つ目は、\ GradleTestのサブフォルダーのルートにあり、 'GradleTest'(GradleTest-GradleTest)というラベルが付いています。これは、開いたときに既にコードがあったものです。したがって、それは私が編集したものです。

** Gradleの設定を確認したところ、[ 自動インポートを使用する]既に有効になっているようです。これにもかかわらず、build.gradleファイルに変更を加えても、ビルドバリアントは自動的に更新されません注:私はまた、ビルド-プロジェクトの再構築、および/またはビルド-プロジェクトの作成を使用してみました。変更を有効にするには、プロジェクトを閉じて、再度開く必要があります。


がのapplicationId代わりにサポートされるようになりましたpackageName
Hamzeh Soboh

回答:


220

Studioの環境設定の[Gradle]セクションで、プロジェクトの自動インポートを有効にすることができます(後でデフォルトで有効にします)。これにより、スタジオでbuild.gradleを編集するたびに再インポートできます。

フレーバーを作成しても、それらにカスタムコードを使用するわけではないため、フォルダーは作成されません。自分で作成する必要があります。

あなたが見れば私のIOの話あなたは私たちがバリアントを作成するために、味とビルドタイプから一緒値に混ぜる方法を見ていきます。

Javaソースの場合:

src/main/java
src/flavor1/java
src/debug/java

3つすべてを使用して、単一の出力を作成します。つまり、同じクラスを定義することはできません。

2つのフレーバーで同じクラスの異なるバージョンを使用する場合は、両方のフレーバーで作成する必要があります。

src/flavor1/java/com/foo/A.java
src/flavor2/java/com/foo/A.java

そして、src / main / javaのコードは

import com.foo.A

選択したフレーバーに応じて、com.foo.Aの正しいバージョンが使用されます。

これは、Aの両方のバージョンが同じAPIを持つ必要があることも意味します(少なくとも、src / main / java / ...のクラスで使用されるAPIに関しては)。

修正された質問に一致するように編集

さらに、相互に排他的なソースフォルダーにのみ同じAクラスを配置することが重要です。この場合、src / flavor1 / javaとsrc / flavor2 / javaが一緒に選択されることはありませんが、mainとflavor1は一緒に選択されます。

別のフレーバーで別のバージョンのアクティビティを提供する場合は、src / main / javaに配置しないでください。

3つのフレーバーがあり、flavor1のカスタムフレーバーのみが必要な場合、flavor2とflavor3が同じアクティビティを共有している場合、他の2つのアクティビティの共通ソースフォルダーを作成できることに注意してください。新しいソースフォルダを作成し、それらを使用するようにソースセットを構成する際に、完全な柔軟性があります。

他のポイントに移ります:

2番目のフレーバーソースフォルダーが青ではないのは正常です。それを有効にするには、2番目のフレーバーに切り替える必要があります。そうすると、内部にパッケージとクラスを作成できるようになります。それまで、Studioはそれをソースフォルダーとは見なしません。将来的には、これを改善してIDEがこれらの非アクティブなソースフォルダーを認識できるようにする予定です。

resフォルダーにリソースファイルを作成できないのも普通のことだと思います。メニューシステムは、これらすべての追加リソースフォルダーを処理するように更新されていません。これは後で来るでしょう。


1
回答の最後にいくつかの新しい要素を追加しましたが、その複製には意味があります。src / main / javaとsrc / flavor1 / javaの両方に同じクラスを置くことはできません。どちらもフレーバー1を選択するときに使用されるためです。私の答えでは、flavor1 / javaとflavor2 / javaのみに同じクラスを配置していることに注意してください。これらは排他的であり、一緒に有効化されることはありません。
Xavier Ducrohet 2013年

ねえザビエル、私のフレーバーで別のバージョンのアクティビティをどのように使用できるかについて、もっと詳しく教えてもらえますか?MainActivityの異なるバージョンを使用したいテストプロジェクトがありますが、両方のapk(flavor1とflavor2)にはmain / javaのバージョンしかありません。MainActivityをmain / java内に配置しないと、起動時にアプリがクラッシュします。
JensJensen

@XavierDucrohetでは、フレーバーに基づいて異なるリソースと異なるコードを用意しますが、同じルートプロジェクトでコードとリソースを混在させることなく、フレーバーに基づいて1つのモジュールまたは他のモジュールを含めることができるように、それらを異なるモジュールに含めますか?それはサポートされていますか?
Valerio Santinelli 2014年

3
@ValerioSantinelliフレーバーごとの依存関係を実行できます。使用flavorCompile ...
Xavier Ducrohet 2014年

@XavierDucrohet私はあなたが提案したものを試しましたが、それは期待通りに機能していません。あなたは私のプロジェクトが構成されているかを確認することができますstackoverflow.com/q/24410995/443136
ヴァレリオSantinelli

19

Androidの「商品の味」

同じアプリの異なるバージョンを使用して、さまざまなホスト、アイコン、またはパッケージ名を操作する方法について尋ねられることがあります。

これを行う理由はたくさんあり、簡単な方法の1つは製品フレーバーです。

build.gradleスクリプトで、前に説明したこのようなことを定義できます。

製品のフレーバー この記事の一部は製品のフレーバーについて考えて書かれているので、それらは何ですか?Androidのドキュメントについて:

製品フレーバーは、プロジェクトによってビルドされたアプリケーションのカスタマイズバージョンを定義します。単一のプロジェクトは、生成されたアプリケーションを変更するさまざまなフレーバーを持つことができます。

それらをどのように定義できますか?定義するフレーバーをbuild.gradleに記述する必要があります。

productFlavors {  
        ...
        devel {
            ...
        }

        prod {
            ...
        }
    }

ここで、アプリの2つの異なるフレーバーを用意します。Android Studioの[Build Variants]タブでも確認できます

バリアントを作成する

複数のパッケージ名

あなたの携帯電話に開発状態のアプリとプロダクション状態のアプリをインストールしたい場合はどうでしょう。ご存知かもしれませんが、同じパッケージ名でインストールできるアプリは1つだけです(携帯電話にインストールされているものと同じ新しいAPKをインストールしようとすると、アップデートを試みます)。

あなたがしなければならない唯一のことは、あなたの製品フレーバーのそれぞれでそれを定義することです:

android {  
    productFlavors {
        devel {
            applicationId "zuul.com.android.devel"
        }
        prod {
            applicationId "zuul.com.android"
        }
    }
}

フレーバーに応じて複数のホストにリクエストを送信する以前と同様に、製品のフレーバー構成フィールドにいくつかのパラメーターを含める必要があります。

android {  
    productFlavors {
        devel {
            applicationId "zuul.com.android.devel"
            buildConfigField 'String', 'HOST', '"http://192.168.1.34:3000"'

        }

        prod {
            applicationId "zuul.com.android"
               buildConfigField 'String', 'HOST', '"http://api.zuul.com"'

        }
    }
}

例として、これをRetrofitと統合して、フレーバーに基づいてどのサーバーを指しているかを処理することなく、適切なサーバーにリクエストを送信する方法を紹介します。この場合、これはZuul Androidアプリの抜粋です。

public class RetrofitModule {

    public ZuulService getRestAdapter() {
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(BuildConfig.HOST)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        return restAdapter.create(ZuulService.class);
    }

}

ご覧のとおり、今定義した変数にアクセスするには、BuildConfigclassを使用する必要があります。

コードで使用できる変数HOST変数は、コードで公開できる唯一のものではありません。あなたは好きなようにそれを行うことができます:

prod {  
    applicationId "zuul.com.android"
    buildConfigField 'String', 'HOST', '"http://api.zuul.com"'
    buildConfigField 'String', 'FLAVOR', '"prod"'
    buildConfigField "boolean", "REPORT_CRASHES", "true"
}

次のようにアクセスできます。

BuildConfig.HOST  
BuildConfig.FLAVOR  
BuildConfig.REPORT_CRASHES  

フレーバーごとに異なるアイコンフレーバーごとに異なるアイコンが必要な場合は、開いているアイコンを視覚的に検出できます(名前でそれを行うこともできます...しかし、スペースに収まりませんでした!)。各フレーバーの新しいディレクトリ構造を定義します。

先ほど使用した例では、develとprodの2つのフレーバーがあります。次に、2つの新しいディレクトリ構造を定義して、必要なリソースを定義できるようにします。

構造

これはstrings.xml, integers.xml, arrays.xml、などの他のタイプのリソースでも機能します。

署名設定を構成する

Gradleビルド構成を使用して、リリースビルドタイプの署名構成を手動で構成するには:

1.キーストアを作成します。キーストアは、秘密鍵のセットを含むバイナリファイルです。キーストアは安全な場所に保管する必要があります。2.秘密鍵を作成します。秘密鍵は、個人や会社など、アプリで識別されるエンティティを表します。3.モジュールレベルのbuild.gradleファイルに署名設定を追加します。

android {
...
defaultConfig {...}
signingConfigs {
    release {
        storeFile file("myreleasekey.keystore")
        storePassword "password"
        keyAlias "MyReleaseKey"
        keyPassword "password"
    }
}
buildTypes {
    release {
        ...
        signingConfig signingConfigs.release
    }
}

}

署名済みAPKを生成します。

署名済みAPKを生成するには、メインメニューから[ビルド]> [署名済みAPKを生成]を選択します。app / build / apk / app-release.apk内のパッケージがリリースキーで署名されました。

ref:https ://developer.android.com/studio/build/build-variants.html#signing,http: //blog.brainattica.com/how-to-work-with-flavours-on-android/



7

で新しいフレーバーを追加した後、プロジェクトリロードする必要があるようですbuild.gradle。その後、ビルドバリアントビューに4つのビルドバリアントが表示されます(ウィンドウの左端からアクセスします)。

追加のソースディレクトリに関しては、あなたが手でそれらを作成する必要がありそうです:src/flavor1/javasrc/flavor2/java。あなたは、「ビルドバリアント」ビューで味を変えることは変更されることがわかります、現在アクティブなソースディレクトリを(それがあるときにディレクトリは青で、アクティブソースディレクトリ

最後に、Gradleのオブジェクトを作成することを意味します「のGradleは、あなたの新しい味のための新しいsourceSetsを作成します」android.sourceSets.flavor1android.sourceSets.flavor2、あなたのbuild.gradleスクリプトでそれらを使用することができます。しかし、これらのオブジェクトは動的に作成されるため、build.gradle(これらを読むことをお勧めします:http : //www.gradle.org/docs/current/userguide/tutorial_using_tasks.html特に6.6:これは、動的タスクの作成。gradleスクリプトはGroovyスクリプトなので、Groovyにも慣れることをお勧めします)


2
インポートノートはBuild Variantsビューだと思いますが、気づきませんでした。
Chris.Jenkins 2013

2

プロジェクトをGradleに移行したときにも同じ問題が発生しました。問題は、ビルドが適切なリソースフォルダーを見つけられなかったことでした。build.gradleのandroid要素の下にこれを追加して修正しました。

sourceSets {
        main {
            res.srcDirs = ['myProject/res']
        }
    }

0

重要で、しばらくの間私をブロックしていたのは、gradleのフレーバー定義内で定義されたパッケージとは対照的に、パッケージと一致する必要があるフレーバー名です。例えば:

src/flavor1/java/com/foo/A.java

一致します

productFlavors {
  flavor1 {
    packageName 'com.android.studio.test.foobar'
  }
}

だが

src/foobar/java/com/foo/A.java flavor1ビルドには使用されません。


0

グラドル:

ビルドタイプの場合、必要なものは次のとおりです。

buildTypes {
   release{
    //proguard, signing etc.
   }
   debug {
    //development
   }
  }
}

そして、フレーバーについては、必要なものを追加します

productFlavors {
    pro {
        applicationIdSuffix '.paid'
        buildConfigField 'boolean', 'PRO', 'true'
    }
    free {
        applicationIdSuffix '.free'
        buildConfigField 'boolean', 'PRO', 'false'
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.