Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure build types vs. product flavors?

Based on this answer https://stackoverflow.com/a/27908019/5156317 I have a follow up question: What makes an app different that speaks for product flavours? I am trying to compare this with my XCode setup which is as follows:

  • Dev App that uses test backend
  • Dev App that uses production backend
  • Test App that uses test backend (enterprise distribution)
  • Test App that uses production backend (enterprise distribution
  • Live App that uses production backend (app store distribution)

My thoughts for the android setup:

buildTypes: debug_test debug_production // no need of enterprise apps since it is possible unsigned apps on any device release

flavors: myApp

Thanks for your support!

like image 897
Fahim Avatar asked Feb 03 '17 16:02

Fahim


People also ask

When would you use a product flavors in your build setup?

When to use Product Flavors. When we want to address the issue of having separate project code for each version of the app while still having one project code. Given a scenario where you have a free and a paid app you can limit features in the free and expose all the other features in the paid version of the app.

What is a build type and a product flavor in android?

Android Product Flavors are also known as Android build types or Android build variants are the native Android app development way to implement different versions of the same application with minor changes. Here is the official Android documentation for the configuration of Android Product Flavors.

What are build types?

Once the new project is created, by default it consists of two build types/variants - debug, release.


2 Answers

Well, I wouldn't specify more build types than debug and release in order to use different backend. Instead, I would use some of these techniques:

  • more flavors,
  • custom build config fields (documentation here),
  • combine multiple product flavors (documentation here).

You can access build types, build flavors and custom fields in the application code using BuildConfig class.

Approach with simple flavors

  • Build types:

    • debug
    • release
  • Flavors:

    • dev
    • test
    • live

Which would result in these build variants (you don't have to use all of them):

  • devDebug
  • devRelease
  • testDebug
  • testRelease
  • liveDebug
  • liveRelease

Approach with combining multiple flavors using dimensions

  • Flavor dimensions:

    • backend
    • target
  • Build types:

    • debug
    • release
  • Flavors:

    • target dimension:
      • dev
      • test
      • live
    • backend dimension:
      • production
      • test

Which would result in these build variants (again, you don't have to use all of them):

  • productionDevDebug
  • productionDevRelease
  • productionTestDebug
  • productionTestRelease
  • productionLiveDebug
  • productionLiveRelease
  • testDevDebug
  • testDevRelease
  • testTestDebug
  • testTestRelease
  • testLiveDebug
  • testLiveRelease

Using build field

Use additional value in build types and build flavors declarations, for example:

buildConfigField "boolean", "production_backend", "false"

or

buildConfigField "String", "backend", "\"production\""

like image 90
Andrzej Zabost Avatar answered Sep 20 '22 07:09

Andrzej Zabost


build.gradle

class Globals {
    static String devDebug = "_devDebug"
    static String devRelease = "_devRelease"
    static String stagingQA = "_stagingQa"
    static String prodRelease = "_prodRelease"
    static String prodDebug = "_prodDebug"

    def firstproduct = "firstproductFP"
    def secondproduct = "secondproductFP"

//     Product key
    static String FP = "FP"
    static String SP = "SP"
}

android {

    buildTypes {
        debug {}
        qa {}
        release {}
    }

    flavorDimensions "client", "backend"
    productFlavors { 

//          First Product (FP)
        FP_dev {    
            dimension 'backend'
            buildConfigField("String", "TEST", "\"FP_dev\"")
        }
        FP_staging {
            dimension 'backend'
            buildConfigField("String", "TEST", "\"FP_staging\"")
        }
        FP_prod {
            dimension 'backend'
            buildConfigField("String", "TEST", "\"FP_prod\"")
        }
        firstproduct {
            dimension 'client'
            ...
        }


//          Second Product (SP)
        SP_dev {    
            dimension 'backend'
            buildConfigField("String", "TEST", "\"SP_dev\"")
        }
        SP_staging {
            dimension 'backend'
            buildConfigField("String", "TEST", "\"SP_staging\"")
        }
        SP_prod {
            dimension 'backend'
            buildConfigField("String", "TEST", "\"SP_prod\"")
        }
        secondproduct {
            dimension 'client'
            ...
        }
}

    variantFilter {
        variant ->
           def needed = variant.name in [
                    Globals.firstproduct + Globals.FP + Globals.devDebug,
                    Globals.firstproduct + Globals.FP + Globals.stagingQA,
                    Globals.firstproduct + Globals.FP + Globals.prodRelease,

                    Globals.secondproduct + Globals.FP + Globals.devDebug,
                    Globals.secondproduct + Globals.FP + Globals.stagingQA,
                    Globals.secondproduct + Globals.FP + Globals.prodRelease
            ]
            variant.setIgnore(!needed)
    }

}

The approach of this solution allows to have multiple client compilations and backend environments for multiple product flavors.

What I did was to associate the development environment of the backend with the compilation of debug android, staging of the backend with qa of android and production of the backend with release of android. Bear in mind that there will be cases in which you need to debug the production environment or obfuscate the development environment, this solution allows it.

  • firstproductFP_devDebug
  • firstproductFP_stagingQa
  • firstproductFP_prodRelease
  • secondproductSP_devDebug
  • secondproductSP_stagingQa
  • secondproductSP_prodRelease

An example when compiling firstproductFP_devDebug:

BuildConfig.java

public static final String FLAVOR = "firstproductFP_dev";
public static final String FLAVOR_client = "firstproduct";
public static final String FLAVOR_backend = "FP_dev";
public static final String BUILD_TYPE = "debug";

It should be noted that within the scope of variantFilter{} you cannot use buildConfigField() to compile values based on the build type and product flavor. This forces us to use flavorDimensions and a larger quantity productsFlavors. Nor can the active build variant be renamed.

IMPORTANT: The values of the variables must match the names of the products flavors

GL

Sources:

  • Build Variants
  • Exclude specific build variants
like image 28
Braian Coronel Avatar answered Sep 20 '22 07:09

Braian Coronel