Jacek Kwiecień
Written by Jacek Kwiecień
Android Developer
Published October 5, 2016

Optimizing Gradle to speed up your build times

It’s a story of how an optimized gradle can reduce the build time to a couple of seconds! Some work done in Android Studio and voilà.

In my previous posts, I wrote about several gradle tricks increasing productivity. I was also complaining about gradle overhead to our build times.

Recently, I struggled with a new project. At some stage, even the slightest change was making me wait more than one minute – 1:30 to be precise! This was the tipping point. I started optimizing and here is the story of how I did it. To get you curious – I got down to a couple of seconds!

Dev flavor with min sdk set to 21

Of course, I have that. My project has 3 flavors – prod, stage and dev. The app is available from sdk 16, but to make my daily work faster, I use dev flavor with minSdkVersion 21. There are some perks of working with flavor set to higher min API than the prod one. Especially, when your app has over 65k methods and needs to use multidex. But that I’ll cover in a different post. The thing is, in my case, minSdkVersion 21 didn’t really help.

No changes – still ages of building  – proguard!

First, I noticed that I have to wait for long every time I run the app from Android Studio. That was suspicious. So, I went through my app build.gradle and found this:

Oh god… I’ve been using the proguard on debug builds all this time. No wonder it consumes so much time on every attempt… I remember I did that to overcome 65k method limit… before I decided to use minSdkVersion 21. I did that because I couldn’t just set minSdkVersion 21 to prod and stage builds, as they had to be minSdkVersion 16. And I didn’t want to use multidex… well, that was wrong. I finally got this stuff together and setup my project to user multidex on prod and stage builds, and to use minSdkVersion 21 instead on dev build. In the end, the setup changed to this:

And the flavors:

Setting flavors this way required some additional setup if I wanted to run prod or stage on the device that runs older android, but that I’ll cover some other time. This step, however, got me from 1:30 to 1:10.

Excluding unnecessary artifacts

I came to the conclusion that I didn’t really need to build release apk from dev flavor. So, I excluded and gained additional couple of seconds this way:

Gradle 3.0

I’ve heard reports of builds speeding up with, currently experimentally supported by Android, gradle 3.0. And I decided to give it a try. It requires some work, though… so it might not be worth the efforts for some developers.

./gradlew wrapper --gradle-version=3.0 command executed from the command line, while in the project repo upgraded my gradle wrapper.

Then I had to upgrade android gradle plugin to beta one:
classpath 'com.android.tools.build:gradle:2.2.0-beta3'

It’s worth to upgrade buildToolsVersion to the latest one in the process.

Now… if you encounter the following error – Unsupported major.minor version 52.0 – you have to  change your jdk to 1.8+. It probably won’t be enough to alter it in project preferences in Android Studio. You might have to edit the info.plist file of Android Studio to enforce using 1.8. Or you can upgrade to Android Studio 2.2. It’s in beta stage now but I’ve been using it without any serious concerns so far. And it might be good for you to know that it has its info.plist already prepared accordingly.

Instant run

When it works, it’s great. It’s especially helpful when working on small changes in layout xml files. It might rerun the app with the changes introduced in seconds. It even keeps your activity, so you don’t have to click through the app again. However, this doesn’t work every time. I’m not sure why but I’m guessing that the activity rerun this way might not be firing all the regular callbacks… but then you can go one step back and restart the activity you’re working on.

Offline work

Last but not least, that was something that after all the previous steps got me down to a couple of seconds! I had no idea how does the gradle offline work affect the build. I had never used the option that might be enabled in Android Studio. I was always online after all, why bother then?

But let’s start from the beginning. I did /.gradlew assembleDevDebug --profile

For some reason, gradle was doing a lot of work under the Dependency resolution section. This section itself took 50 seconds! In there it compiled every possible artifact, including tests. Here is just a small part of the list:

Dependencies Duration
All dependencies 50.059s
:app:_prodDebugCompile 6.382s
:app:_stageDebugCompile 3.628s
:app:_devReleaseCompile 3.317s
:app:_mockDebugApk 3.259s
:app:_stageReleaseCompile 3.144s
:app:_prodDebugApk 3.126s

I’m not sure why it does that, maybe I don’t get something but the bottom line is: offline work makes it mostly go away! Boom – now sit back and enjoy your work life.

What do I do with all that time now?

No more funny sites browsing during the builds, eh? I guess it’s a fair deal – you’ll be done with your work faster! 😉 But seriously, try this and share your thoughts. Did it help you? How much? I’m all curious!

I wanted to thank my fellow colleague Kamil Zych for bearing me during the whole process during the weekend! Beers on me!

Written by Jacek Kwiecień
Android Developer
Published October 5, 2016