Config for specific gradle flavor combination

2020-07-11 07:23发布

问题:

I am wondering if it is possible to supply files or configuration settings for a specific flavor group combination. For example, I have 2 flavor groups, with 2 different flavors each:

Flavor Group: Version

  • v2
  • v3

Flavor Group: Type

  • free
  • full

When ordered "Type", "Version" I am able to build 4 different flavors of my app:

  • FreeV2
  • FreeV3
  • FullV2
  • FullV3

And my source tree looks like this:

/src
    /free
        /res
    /full
        /res
    /v2
        /java
        /res
        AndroidManifest.xml (features and permissions for v2 flavors)
    /v3
        /java
        /res
        AndroidManifest.xml (features and permissions for v3 flavors)

This is exactly what I want, and works very well for my project. However, I wish I could provide files for a specific flavor group combination. For example, I want to provide different AndroidManifests for FullV3 and FullV2. I don't think this is possible, or? For example:

/src
    /free
        /res
    /full
        /res
    /v2
        /java
        /res
        AndroidManifest.xml (features and permissions for v2 flavors)
    /v3
        /java
        /res
        AndroidManifest.xml (features and permissions for v3 flavors)
    /fullv3
        AndroidManifest.xml (features and permissions for full v3 only!)
    /fullv2
        AndroidManifest.xml (features and permissions for full v2 only!)

I would be nice to be able to do this in the gradle build file as well:

productFlavors {
    free {
        packageName ...
        flavorGroup "type"
    }
    full {
        packageName ...
        flavorGroup "type"
    }
    v2 {
        packageName ...
        flavorGroup "version"
    }
    v3 {
        packageName ...
        flavorGroup "version"
    }
    fullv2 {
        ...  <-- specifically for the full-v2 combination
    }
    fullv3 {
        ...  <-- specifically for the full-v3 combination
    }
}

Note: one solution would be to only have 1 flavor group and define the 4 flavors explicitly:

  • freeV2
  • freeV3
  • fullV2
  • fullV3

However, this is not a viable solution for me since I would have to duplicate all the version specific code for the free and full flavors of each version.

回答1:

This functionality was added in version 0.7.0 of the Android plugin for Gradle

http://tools.android.com/tech-docs/new-build-system <--As of 1/6/14, this link is active

You can now have a variant specific source folder if you have flavors.

  • Only for app (not library or test). Name is src/flavorDebug/... or src/flavor1Flavor2Debug/
    • Note the camelcase naming, with lower case for first letter.
  • Its components (res, manifest, etc...) have higher priority than components from build type or flavors.
  • There is also a "flavor combination" source folder available when more than one flavor dimension is used. For instance src/flavor1Flavor2/
    • Note that this is for all combinations of all dimensions.
    • Its priority is higher than single-flavor sourcesets, but lower than build-types.

Update 1/30/2014

IntelliJ IDEA v13.0.2 (Build 133.696) now supports Android Gradle Plugin changes made in 0.7.0



回答2:

Files will be merged when the flavors come together. So if you have a manifest in full and in v3, they will be combined when fullV3 is generated. This way you can get the combo generated.



回答3:

As per the question asked you want different AndroidManifest file for Full version of both v2 and v3. So instead of going with flavors for full and free, you can use combination of flavors and buildTypes as per your convenience.

For example

I know full and free should be product flavors not build types but your requirement says that full and free are your buildTypes and v2 and v3 are your app flavors

buildTypes {

  debug {
     runProguard false
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'

  }

  full{
     runProguard false/true
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
     signingConfig signingConfigs.prodSigning // write your signingConfig

   }

  free{
     runProguard false/true
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
     signingConfig signingConfigs.prodSigning // write your signingConfig

    }
 }

 productFlavors{

   v2 {
     //required configuration for full version

   }

   v3 {
      //required configuration for full version

    }

  } 

Now your project structure should look like this .

  --src
    ---main
      ----java
      ----res
      ----Manifest
    ---full
      ----java
      ----res
      ----Manifest(Manifest you want for Full Version)
    ---free
      ----java
      ----res
      ----Manifest (Manifest you want for Free Version)
    ---v2
      ----java
      ----res
      ----Manifest
    ---v3
      ----java
      ----res
      ----Manifest

After Sync with Gradle this will give combinations of build types in build variant tab in left pane in AS and will create different tasks for the same.

Go to Build Variant and generate the build from drop down according to your choice.

It will give you Build Variants like this



回答4:

To set configuration for each flavor combination in your build file you could use the solution I proposed here: https://stackoverflow.com/a/26585241

You can then use and variantFilter to iterate through all flavor combinations and match on the name of each combination (just like the name used when creating "flavor combination" source folders where you can place specific resources as mentioned in the answer from @abest):

android.variantFilter { variant ->
    def flavorString = ""
    def flavors = variant.getFlavors()
    for (int i = 0; i < flavors.size(); i++) {
        flavorString += flavors[i].name;
    }
    if(flavorString.equalsIgnoreCase("fullv2")) {
        variant.getDefaultConfig().applicationId "com.example.fullv2"
    }