It’s a few weeks after I/O ’17 now and I’m sure you’re all making your way through the many sessions at the conference.
One of the more practical sessions at I/O was How to speed up your slow Gradle builds. In this session the tools team presented 10 great tips for speeding up your gradle builds 🎉
I decided to compile these tips into a handy list for easy reference, so here it is 💡
Disclaimer: these tips are not mine and are taken from the recording of the IO Session How to speed up your slow Gradle builds. The explanation of this tips is my own wording.
All credit goes to Google and the Tools team.
The tools team are constantly improving the Android Gradle Plugin and improving build speed, so this tip is super easy. Always use the latest version!
buildscript {
repositories {
google()
}
dependencies {
classpath ‘com.android.tools.build.gradle:3.0.0-alpha3’
}
}
If you’re unsure what Multidex is, have a read of this article.
Native multidex on devices running API 21 and above has very little performance impact, but legacy multidex on older devices does!
When developing your app, you should avoid using legacy multidex.
This involves setting your app’s minSdkVersion to 21, and developing a device that is at least running API 21.
The good news is if you are using a newer version of Android Studio, it will set the minSdkVersion for you, so you shouldn’t need to do anything except hit the run button 🎉
If you aren’t using ABI or Density splits in your app, you can skip this tip.
If you are, you should disable this for development builds as it slows down build times.
This can be achieved by passing a variable to gradle when running a development build, and disabling the splits when it’s present:
android {
if (project.hasProperty(‘devBuild’)){
splits.abi.enable = false
splits.density.enable = false
}
}
When building from the command-line:
./gradlew assembleDevelopmentDebug -PdevBuild
When building from Android Studio:
Add -PdevBuild to the Command-line options field of the Preferences -> Build, Execution, Deployment -> Compiler settings in Android Studio:
Resources take up a sizable amount of space in your APK, and packaging all these resources slows down your build.
For development builds, you can tell Gradle only to package the resources you care about, for the device you are developing on.
productFlavors {
development {
minSdkVersion 21
//only package english translations, and xxhdpi resources
resConfigs (“en”, “xxhdpi”)
}
}
PNG optimizations are enabled by default, but are not needed for development builds. Disable them to speed up your builds.
android {
if (project.hasProperty(‘devBuild’)){
aaptOptions.cruncherEnabled = false
}
}
Instant Run gets a bit of a bad rap, but when it works it can really save you time.
Instant Run in Android Studio 3.0 has a lot of improvements, and should be a lot more stable.
Give it a go!
Gradle is super flexible and you can do some really cool things in your build scripts. But if you aren’t careful you can really slow down builds.
This little snippet of code sets the versionCode to the current time — Useful for testing, but it means that for every build, the manifest is changed causing unnecessary processing and packaging.
//this is BAD!
def buildDateTime = new Date().format(‘yyMMddHHmm’).toInteger()
android {
defaultConfig {
versionCode buildDateTime
}
}
Instead, disable this on development builds:
def buildDateTime = project.hasProperty(‘devBuild’) ? 100 : new Date().format(‘yyMMddHHmm’).toInteger()
android {
defaultConfig {
versionCode buildDateTime
}
}
The rule of thumb here is make sure any custom logic, plugins or libraries are only modifying files when necessary, rather than every build.
Another common pitfall is Crashlytics build IDs. Crashlytics will generate a new build id for every build.
This can (and should) be disabled for debug builds with a single line:
apply plugin: ‘io.fabric’
android {
buildTypes {
debug {
ext.alwaysUpdateBuildId = false
}
}
}
Using dynamic dependency versions is a big no-no for a couple of reasons:
Always use specific dependency versions!
Be careful of the amount of memory you’re giving to Gradle.
For a great explanation on Gradle memory settings and Dex In Process, read this article by Reto Meier.
You’ll want to play around the amount of memory you give Gradle:
org.gradle.jvmargs=-Xmx1536m
And since the release of Dex In Process, this old optimization is no longer needed:
dexOptions {
javaMaxHeapSize = ‘4g’
}
Gradle Caching is new in Gradle 3.5, and when enabled Gradle will cache and reuse outputs from previous builds.
This works for any build, any branch changes, and across projects.
Android Studio 3.0 takes even more advantage of this cache, so make sure you have it enabled:
# Set this in gradle.properties
org.gradle.caching=true
Watch the session, you’ll learn a lot!
If you liked this article, make sure to ❤ it below, and follow me on twitter!