top of page
Writer's pictureDon Peter

Gradle Flavors: Building multiple Android App variants with single codebase



Gradle Flavors: Building multiple Android App variants with single codebase

Gradle Flavors, also known as product flavors, allow developers to create multiple variants of their app within a single codebase. Each flavor can have its own unique configuration, resources, and dependencies, enabling customization based on factors such as branding, feature sets, or target audiences.


If you're developing free and paid versions of your app, adapting it for different languages or regions, or incorporating variations for testing purposes, Gradle Flavors offer unparalleled flexibility.


Why Use Gradle Flavors?

  1. Customization: With Gradle Flavors, developers can easily tailor their app to suit specific user segments or market requirements. This level of customization fosters better user engagement and satisfaction.

  2. Efficiency: Rather than maintaining separate codebases for different app variants, Gradle Flavors streamline the development process by centralizing code while allowing for variant-specific configurations. This results in reduced complexity and faster iteration cycles.

  3. Consistency: By defining variant-specific resources and dependencies within the Gradle build script, developers ensure consistency across different app versions while minimizing the risk of errors or inconsistencies.

  4. Market Segmentation: For businesses targeting diverse demographics or regions, Gradle Flavors facilitate the creation of specialized versions of the app tailored to each market segment's preferences and needs.


Free and Pro Versions

Let's illustrate the power of Gradle Flavors with the above scenario – creating free and pro versions of an app. Suppose you have an app called "WeatherApp" and want to offer both a free version with basic features and a paid pro version with additional functionalities.


android {
    ...
    productFlavors {
        free {
            dimension "tier"
            applicationId "com.example.weather.free"
            versionCode 1
            versionName "1.0"
            // Define flavor-specific configurations
            buildConfigField "boolean", "IS_PRO_VERSION", "false"
        }
        pro {
            dimension "tier"
            applicationId "com.example.weather.pro"
            versionCode 1
            versionName "1.0"
            // Define flavor-specific configurations
            buildConfigField "boolean", "IS_PRO_VERSION", "true"
        }
    }
	
	buildTypes {
        debug {
            // Debug-specific configurations
            ...
        }
        release {
            // Release-specific configurations
            ...
        }
    }
    ...
}

In this example, we define two product flavors: 'free' and 'pro', each with its own unique applicationID. We can then customize the behavior, features, and resources specific to each flavor, such as limiting certain features to the pro version or displaying different branding elements.


In the above example, we define two build types. "debug" and "release," each with its own configurations. These configurations might include signing configurations, proguard rules, or other build-specific settings.

With the flavors and build variants defined, Gradle will generate the following build variants:

  1. freeDebug

  2. freeRelease

  3. proDebug

  4. proRelease

Developers can then use these variants to build and test different versions of the app. For instance, they can build the "pro" release variant to generate a signed APK for distribution to users who have purchased the pro version of the app. Similarly, they can build the "free" debug variant to test new features or changes specific to the free version of the app.


Android Project Structure with Gradle Flavors

In the above example, the folder structure for the Android project would typically look like this:


- app
  - src
    - free
      - java
        - com
          - example
            - weather
              - MainActivity.java
              - ...
      - res
        - layout
        - drawable
        - values
        - ...
    - pro
      - java
        - com
          - example
            - weather
              - MainActivity.java
              - ...
      - res
        - layout
        - drawable
        - values
        - ...
    - main
      - java
        - com
          - example
            - weather
              - MainActivity.java
              - ...
      - res
        - layout
        - drawable
        - values
        - ...

Here's a breakdown of the folder structure:

  • app: This is the main module of the Android project.

  • src: This directory contains the source code and resources for different build variants.

  • free: This directory contains the source code and resources specific to the "free" flavor.

    • java: Java source code files for the "free" flavor.

    • com.example.weather: Package directory.

    • MainActivity.java: Example activity class.

    • Other Java files specific to the "free" flavor.

    • res: Resource directory for the "free" flavor.

    • layout: XML layout files.

    • drawable: Image resources.

    • values: Resource files such as strings, colors, dimensions, etc.

    • Other resource directories specific to the "free" flavor.

  • pro: This directory contains the source code and resources specific to the "pro" flavor. The structure is similar to the "free" flavor but with resources and code specific to the "pro" variant.

  • main: This directory contains the main source code and resources shared among all flavors and build types. It serves as the base for all variants and contains code and resources common to both "free" and "pro" flavors.


By organizing the source code and resources in this way, Gradle can easily build different variants of the app by combining the contents of the "main" directory with the specific contents of each flavor directory (free and pro).


Leveraging Gradle flavors and build variants empowers Android developers to efficiently manage and customize multiple versions of their apps, catering to diverse user preferences and market requirements while maintaining codebase integrity and flexibility.

Blog for Mobile App Developers, Testers and App Owners

 

This blog is from Finotes Team. Finotes is a lightweight mobile APM and bug detection tool for iOS and Android apps.

In this blog we talk about iOS and Android app development technologies, languages and frameworks like Java, Kotlin, Swift, Objective-C, Dart and Flutter that are used to build mobile apps. Read articles from Finotes team about good programming and software engineering practices, testing and QA practices, performance issues and bugs, concepts and techniques. 

Monitor & Improve Performance of your Mobile App

 

Detect memory leaks, abnormal memory usages, crashes, API / Network call issues, frame rate issues, ANR, App Hangs, Exceptions and Errors, and much more.

Explore Finotes

bottom of page