Tracking Android project build times

A multi-part series on how to track Android build times and applicable system information for a team of developers

Sean Weiser
Livefront
4 min readFeb 20, 2023

--

How many hours have you sat in front of Android Studio looking at the “Gradle Build Running” message, just waiting for your application to build and deploy to your device? For large applications shared by dozens of developers, measuring this number is important to figuring out how much time might be going to waste. Previously I’ve written on ways to reduce build times, but it’s vital to get an initial data point to see just how much improvement is being made as you modify your build setup.

The build times of any large application are going to vary to some degree, even for a single developer, based on a number of factors. When you extend that to multiple developers spread across the globe, each with different hardware and software setups, that number is going to vary wildly. While your core team might all have the latest and greatest hardware, you might have a team of contractors using older machines that you have little control over. It’s important to understand how much those build times vary for all of your developers.

As I mentioned in one of my previous articles, I am not a Gradle expert, but am able to hack together something that works. Usually. So there might be improvements that could be made to the code that follows, but it does get the job done.

Our overall goal is to measure the run times of each developer’s build process, along with gathering vital system information. I recommend not stuffing all of your code into the build.gradle file. We have a separate Gradle file that we call buildTasks.gradle that is applied within build.gradle in order to keep everything orderly.

The first step is to check each of the build tasks and determine if it should be measured. We’re interested in any task that compiles the app and sends it to the device. Those tend to be tasks that start with the word “assemble”. That will skip over tasks like lint checks. We also can skip over test-related tasks. Those task names will end with “Test”. So we’ll happily measure a task called assembleDebug, but will ignore a task called assembleDebugAndroidTest.

As an organization we only wanted to measure the build times within Android Studio. We intentionally ignore builds from the command line or through CI. This is entirely up to you and your company, so the following snippet is useful for my project, but optional for anyone else.

If the IDEA version property can’t be found, the build isn’t occurring in Android Studio (or some other IDEA IDE), and we immediately return. Otherwise we begin measuring and gathering data:

startTimeSec is immediately set while creating this task. elapsedTimeSec is determined after the task is actually run. This is the number we’re actually after, but we also want to gather additional data about the hardware and software this build is running on. So part of our script determines system specific information about the machine itself. I’ll cover that in the next article, but for now the important part is detecting the operating system:

Each hardware family has their own script of OS-specific commands that gets run. A blob of JSON with various machine specs is returned (if everything goes smoothly) written to output, similar to:

Note the error object that we passed into consumeProcessOutput. If any issue crops up while running those external scripts, a message will be populated in that object. Rather than try to recover from the error, we just immediately return and kill the task if necessary.

If everything runs successfully we consume the JSON and transform it to a map we’ll be able to update later. I’m using JsonSlurper, but any JSON parser will do:

From here we can either modify existing specs into something more readable:

or cleanup values for whatever reason:

or add software specs:

The organization’s iOS app also was setup to measure their build times, so we hardcoded the platform to “Android” within our script.

Finally we add the actual build time. We include the time both in seconds and minutes, but it’s up to you how you want it presented:

Now that you have the desired hardware and software specs, you’re free to display it or save it however you want. Ideally you’ll gather this information for each developer over time and consolidate it to analyze later. That’s where a cloud-based logging or analytics service will be useful. I’ll cover different options further in the next article, but for now let’s just print it out to the console:

The final output of the overall task will look something like:

Finally, hook everything up in your application’s build.gradle file:

You can take a look at the complete buildTasks.gradle file here.

As mentioned throughout this article, there are a few details missing that I’ll cover in the followup article: mainly how to gather hardware-specific information, and where to send this data once you’re done. But for now you should be able to successfully log that information each time you run a build locally. Hopefully that’s enough to help reveal how much time you might be wasting just waiting for your builds to finish.

Sean works at Livefront, where we try to keep build times short.

--

--