Android Build Variants

One of the cool things about developing an application for the first time is learning something new at every step of the process.  Sometimes the learning is easy-peasy, and at other times you check the mirror every few minutes to see if you’ve sprouted any grey hairs.  But no matter the difficulty, getting through that obstacle is one of the best feelings a developer can experience.

Looking back, one of the most annoying obstacles I encountered was the creation of build variants for the application.  In order to explain build variants, it might help to understand why we need them in the first place.  Most applications today make network calls to servers to perform operations behind the scenes. In order to do that, an application needs a server that handles specific requests to store, retrieve, or change data.  So, when you pull up an application as a user, you’re probably doing some communication with a server somewhere! However, while you use the app, developers are out there working on that application to make it better.  They might be building a new feature into version 1.1 while you’re still on version 1.0.  In order to work with version 1.1, the server needs to be updated! Well, what if the developers changed the server you’re using to help them test their version? Chaos! That’s where a development server and a production server come in.  One is used by the development team and can be changed and messed with as much as they want, and one is always used for the application end-users, the people who need consistent functionality.

Still with me? Great. Now let’s think about the front-end, the application itself. You’re a developer, and you need to be able to use both aforementioned servers.  You need to be able to tell your phone to communicate with the development server to test new features but also quickly be able to tell it to talk with the production server to replicate bugs that are currently out there in the real-world.  How do you give the application this flexibility? You guessed it, build variants.

The phone and servers communicate using an Application Programming Interface (API).  For instance, an API might specify a method called /get_countries. The phone visits the API and specifies that method, and the server returns all the countries that are in its database.  Easy, right?  Usually this method is appended to a URL, like so: https://appproductionserver.com/get_countries. That might be the production URL, while the development URL is https://appdevelopmentserver.com/get_countries.  So, when I build my application to test, I need to make sure all calls go to the URL with development in it, and the production version calls must go to the URL without development! If there are just a few calls made in the entire application, it might be easy enough to make the change manually in the code. But most applications will have dozens and dozens of calls to different methods being made in different classes, and it’s just not efficient to do a manual change. So, how can I change ALL the calls in my codebase with the click of a button? Let’s find out!

In an Android project, the normal file path to the codebase is app/src/main/java/my/package/name. Inside your main package sit all of your classes.  Well, we can create different build variants using a few simple steps:

  1. In app/src, create two folders that will sit alongside the main folder–for example, prod and stage.
  2. Inside those two folders, create a file structure that replicates the one in the main folder. So if main contains java/my/package/name, then your prod and stage folder should contain java/my/package/name.
  3. Inside the last folder (in this case the “name” folder), create the class that needs to change based on the variant.  For example, maybe you have a URL.java class, which specifies ALL of the URLs for the application. In the stage version of the class, all of the URLs are to the test server, and in the prod version all the URLs hit the prod server.

Great, now we have the correct file setup. Next we need to tell Android Studio how to find them.

In our build.gradle file, we need to specify the product flavors:

productFlavors {
    prod {
        applicationId "my.application.prod"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 14
        versionName '0.3.6'
    }
    stage {
        applicationId "my.application.stage"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 15
        versionName '0.3.7'
    }
}

Once we do this, we can easily go to “Build” in the toolbar, and choose “Select Build Variant”. You’ll see four options there: prodDebug, prodRelease, stageDebug, and stageRelease.  You’ll mainly toggle between the debug options, and only use prodRelease when you’re ready to build and release a new production version! Don’t be worried if your compiler freaks out and throws a ton of errors when you switch variants, just do a project clean and they should resolve!

Hopefully this article has helped you to understand the need for build variants and how to implement them.  You can also use them to specify different names for the application like “MyApp – Dev” for development and “MyApp” for production.  I’ll leave you to figure out how to do that (Hint: You’ll want to replicate a strings.xml file like we did for our URL.java file)! That way, you can install both versions on your phone at the same time and tell which one is which!

Was this helpful? Have any other tips for build variants? Please let us know in the comments below!

Happy coding!

Sincerely,
Brandon from The Bunch

Leave a Reply

Your email address will not be published. Required fields are marked *