Disable Android pre dexing on CI builds

In Android builds, pre dexing helps to speed up the build for incremental builds. On a CI server, where you usually run a clean build, pre dexing is only adding extra time to the build without any added value. There’s already a tip on the Tools site on this, but how do you disable pre dex for all project on your build server?

Lucky for us, Gradle got us covered. When executing builds, Gradle applies a global configuration script called an init script. Quoting from the Gradle documentation:

There are several ways to use an init script:

Specify a file on the command line. The command line option is -I or –init-script followed by the path to the script. The command line option can appear more than once, each time adding another init script.

  • Put a file called init.gradle in the USER_HOME/.gradle/ directory.
  • Put a file that ends with .gradle in the USER_HOME/.gradle/init.d/ directory.
  • Put a file that ends with .gradle in the GRADLE_HOME/init.d/ directory, in the Gradle distribution. This allows you to package up a custom Gradle distribution containing some custom build logic and plugins. You can combine this with the Gradle wrapper as a way to make custom logic available to all builds in your enterprise.

Now we still need a script to serve as our init.gradle. Here's my take on that:

allprojects {
project.plugins.whenPluginAdded { plugin ->
        if ("com.android.build.gradle.AppPlugin".equals(plugin.class.name)) {
            println "Disable pre dexing for module ${project.name}"
            project.android.dexOptions.preDexLibraries = false
        } else if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) {
            println "Disable pre dexing for module ${project.name}"
            project.android.dexOptions.preDexLibraries = false
        }
    }
}

While most of this script should be pretty obvious, let's run through it step by step:

  • This block is applied to all projects using the Gradle allprojects block
  • When a plugin is added during the configuration phase, we check if the plugin class name matches any of the known Android plugins
  • If it does, we disable pre dexing for that (sub)project

Once added, you should see “Disable pre dexing for the module …” when a Gradle build is executed, and your builds should be a little bit faster!



Questions, remarks or other feedback? Discuss this post on Google+