Scaling Android Apps with Gradle! (BuildTypes, ProductFlavors)- Part 1

Sahil Jain
OLX Engineering
Published in
4 min readMay 31, 2022

--

With an increasing feature set and business requirements, modern Android Apps are becoming more complex than ever. OLX is no different than this. OLX operates in multiple markets (with a plan to expand in a few more :) ) and each market has its own defined feature set. It becomes really important and a challenge to make sure the OLX app is configurable and flexible enough to scale to multiple markets with minimal code changes.

Gradle is a powerful build system that compiles app resources and source code and packages them into APKs or Android App Bundles that one can test, deploy and distribute.

The below sections give an overview of how we employ gradle capabilities at OLX to configure builds and cater to multiple markets.

Build Types

Build Types are very helpful in defining properties that gradle can use while building and packaging the app related to the development lifecycle. We use the “debug” build type to configure debug build options like enable debug mode, disable Crashlytics, and sign the app with debug key to create the debug apk or aab. On the other hand, we use the “release” build type to obfuscate the code, shrink the resources and finally sign the build with the release key for distribution.

“debug” and “release” build types to configure debug and release Build Variants

Build types are not only limited to “debug” and “release” types. You can define as many build types and configure them accordingly. For eg. the “staging” build type can be configured to point the build to the “Staging” environment.

“staging” build type to configure staging environment

The “initWith” property allows copying properties from other build types. In this, we initialize our staging build type with “debug” properties, append the application id with “.debugStaging” and change the host endpoint.

Product Flavors

Defining Product flavors is an excellent way to configure and release different versions of the app without maintaining multiple codebases. This is an extremely powerful feature specifically for organizations working on Whitelabel apps or where the feature set varies from market to market. Product flavors can be customized to use different codes and resources while sharing and reusing the parts that are common to all the versions of the app.

To begin with, one can define the default attributes in the “defaultConfig{}” block. This is the place to define the base configuration for all the flavors and each flavor can override any of these values in their respective “productFlavors{}” block.

“defaultConfig” block to define default properties

You can define default properties like “minSdkVersion”, “targetSdkVersion” and other properties which usually remain unchanged for all the flavors (Although you can override them in case you need to).

Use “buildConfigField” to define properties that need to be accessed from *.java or *.kt files. In the code snippet above we have defined “SHOW_ADS” and “SMS_COMMUNICATION” as feature flags and configured “false” as the default value.

In case you want to access the properties from within resource files like strings.xml or AndroidManifest.xml, use “resValue” to define such properties. In the code snippet above we have defined “google_client_id” as a resource value so that it can be accessed from AndroidManifest.xml. Additionally, you can also use conditional expressions to define properties based on certain conditions.

Now let’s suppose we need to enable “SHOW_ADS” and “SMS_COMMUNICATION” features for a certain version of the app but we want the same default behavior (Disabled by default) for the rest of the versions. We can easily achieve this by creating a separate flavor and overriding the properties as per the needs.

“WithAdsEnabled” product flavor to override the default behavior

“WithAdsEnabled” is a flavor defined inside android{} block with “SHOW_ADS” and “SMS_COMMUNICATION” feature flags set as true which override the default properties. “applicationIdSuffix” ensures the build variant for this newly created flavor has “applicationId” with suffix as “.WithAds” and thus ensuring we can publish it as a separate app on PlayStore.

That's it!! With this setup, we can configure different build types keeping our codebase flexible, scalable, and readable.

Summary

With this, we come to an end to the first part of this series where we discovered how at OLX we scale the android app by configuring gradle through different “build types”, “product flavors”. The second part will go a step ahead and talk about how at OLX we fine-tune the gradle by configuring different “source sets” in our codebase as per the build types and product flavors.

I hope you enjoyed reading it and found it helpful ✌

Please direct your feedback or queries to the comment section. You can also reach me directly on LinkedIn or by Email. At last, if you found the post useful don’t forget to hit the clap icon more than once :)

At last, we are hiring at multiple levels for our Android team. Join and be a part of incredible growth. Visit our OLX careers page to view all the open positions.

I wish you luck :)

--

--

Technical Architect | Android Chapter Lead | Domain Expert @OLX Group.