71

Building my Android app takes about 90 seconds ("fast"), up to 3 minutes for each update to my code. It's a complete waste of time as it really and I assume a solution must be within reach. I tried investigating the issue and found different blog-posts and SO answers with suggestions, most of which I've tried.

  • I have the gradle.properties file with org.gradle.deamon=true
  • I run on Android Studio with Gradle Prefence to do offline work (improved, but still slow)
  • I run on command line (which is faster, but still slow)
  • In build.gradle, defaultConfig, I have multiDexEnabled set to false
  • In build.gradle, dexOptions, I have preDexLibraries set to false
  • In gradle-wrapper.properties I fetch a recent gradle version (2.8) (the significant speed changes happened on 2.4)

The process that seems to take long, about 85% of total build time is :app:transformClassesWithDexForDebug

What is that process actually doing? I can find people who have crashes on it, but it works fine for me, except for the fact that it takes a lot of time. And do I need it, since I don't really need Dex at this point?

Also, I have 13 dependencies and 3 testCompile dependencies. I already point to specific play packages, so I'm not compiling stuff I don't need. If I understand things correctly, gradle is building all those libraries each project build as well. If that is correct, is there a way to skip that? Can I build them myself as wrapped-up libraries and include them without the need for them to be processed each time? That might make me lose some flexibility for future changes to dependencies, but at this point I feel like I'm losing over an hour a day easily on waiting for gradle. I'm not sure if flexibility is worth that much to me.

I'm looking forward to get any pointers on how I can improve my build process. Thank you in advance.

Justin Hammenga
  • 1,091
  • 1
  • 8
  • 14
  • 15
    What a relief to know that there is someone out there in the exactly same situation as I am now! Have you made any progress in the meantime? Thank you! – sjkm Jan 22 '16 at 17:07
  • It's been quite a while since I posted this and tried each and every suggestion I came across, with varying degrees of success. None really boosted the build speed to something that feels acceptable, until the release of Android Studio 2.1 as @markdb314 mentioned. Although perhaps available before, only since this version is it clear to do the dex-step in process. This significantly dropped my build time to on average 20-30 seconds. – Justin Hammenga May 17 '16 at 12:31
  • Just curious, are you using the new data binding framework? – tir38 Jul 04 '16 at 23:10
  • No, I'm not using the data-binding framework in the project that had these problems. – Justin Hammenga Jul 05 '16 at 08:01

6 Answers6

34

Edit: At this point, I recommend running Android Studio 2.x side by side with your 1.5 installation. You get access to instant-run, which really helps as well as all the updated tools. If you are staying on 1.5 read on...

I have managed to speed up Android Studio 1.5 debug builds from 2 minutes to 30 seconds. This might not work with your command-line execution, but might be faster.

Using this config, your first IDE build takes the same amount of time, but Incremental builds are faster, even if you modify classes. You lose some gain if you modify attached libraries.

Step 1. (If you're fortunate enough to target minSdkVersion of >= 21 already, skip this.)

@vanomart 's answer of having a minSdkVersion debug flavour of >= 21 is not wrong, but the only part necessary is adding the following to module (app) build.gradle and ensuring you target dev while debugging in your Build Variants tab:

android {
    [...]
    productFlavors {
        dev {
            minSdkVersion 21 //The important bit.
        }
        prod {
            minSdkVersion 15 //Example. Set to your real requirement.
        }
    }

Step 2. Pre-dexing libs.

In your module (app) build.gradle set the following config. This is faster for IDE builds, not so much for builder-servers who start from scratch every build.

android {
    [...]
    dexOptions {
        preDexLibraries true
        javaMaxHeapSize "2g" // Use gig increments depending on needs
    }

Source, doing (partly) inverse of "Improving Build Server performance": http://tools.android.com/tech-docs/new-build-system/tips#TOC-Improving-Build-Server-performance

Step 3. Make sure you're using latest buildToolsVersion in module (app) build.gradle.

android {
    buildToolsVersion "23.0.2"
    [...]

"... update the build tools version in all your modules to the latest (23.0.2). [...] it will use a new faster version of dex, which helps both instant run and a full build be a bit faster."

Source: http://tools.android.com/tech-docs/instant-run

Step 4. Use latest Gradle build tools

In your project build.gradle, set to latest (currently 2.0.0-alpha6)

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.0.0-alpha6'

Updates list: http://tools.android.com/tech-docs/new-build-system

Step 5. Use latest Gradle wrapper. Modify gradle-wrapper.properties, update this line to use 2.10:

distributionUrl=https\://downloads.gradle.org/distributions/gradle-2.10-all.zip
#Alternative url if the above does not work:
#distributionUrl=https://services.gradle.org/distributions/gradle-2.10-all.zip

In Android Studio preferences, ensure you have "Use default Gradle wrapper" selected. I recommend restarting Android Studio to ensure the Gradle daemon restarts.

"In many cases, Gradle 2.9 is much faster than Gradle 2.8 when performing incremental builds."

Source: docs.gradle.org/current/release-notes

Cristan
  • 12,083
  • 7
  • 65
  • 69
dyson returns
  • 3,376
  • 4
  • 16
  • 20
  • thank you very much! my gradle build is now 50% faster (from 2 min to 1 min)! – Luca Ziegler Dec 27 '15 at 14:27
  • 3
    I've followed every step and set up everything correctly. It is still fu*** slow... What a crap software. Google is disappointing me extremely. Any progress in the meantime? But hey the build time decreased from 6 min to 56 seconds! So thank you very much for your great help! – sjkm Jan 22 '16 at 18:01
  • Thank you dyson returns. My gradle speed up notably, from 2.5 min to just a few seconds in some cases. – Jose Ramon Garcia Feb 01 '16 at 21:50
  • In my setup I have "Legacy Multidex" on, shrinkResources on, minifyEnabled on, and proguard running. I've try many different combinations of all of the suggestions related to this topic. In the end, the only thing that worked for me was to turn off "Instant Run" in Android Studio 2.0. My build went from 6 mins 30 secs, to 1 min 41 secs. – Eric Schlenz Apr 12 '16 at 16:17
  • Wow... Just the tip about the dexOptions took my builds from 4 minutes down to 40ish seconds. Still pretty bad for this tiny application, but _amazing_ by comparison! – joshmcode Mar 09 '18 at 06:21
  • IDE lint error on executing Step 1: `In the past, our documentation recommended creating a dev product flavor which has a minSdkVersion of 21, in order to enable multidexing to speed up builds significantly during development. That workaround is no longer necessary, and it has some serious downsides, such as breaking API access checking. In recent versions of the IDE and the Gradle plugin, the IDE automatically passes the API level of the connected device used for deployment, meaning that you get the same speed benefits as the dev product flavor but without the downsides.` – Sagar Jun 02 '19 at 07:12
14

Upgrading to Android Studio 2.1 and the Android Gradle Plugin v2.1.0 has largely fixed this problem for me. After installing the updated IDE, you should be prompted to update your Gradle plugin as well. You'll know you have the right version if your root build.gradle file has the following line:

classpath 'com.android.tools.build:gradle:2.1.0'

IMPORTANT: In addition to upgrading, you also need to increase the amount of memory allocated to the Gradle daemon to 2048mb, so it can perform this expensive dex-ing step in process. To do so, add the following to your root gradle.properties file:

org.gradle.jvmargs = -Xmx2048m

I had similarly slow build times as experienced in the question above, but after upgrading my build speeds increased dramatically. See the release notes for the Android Gradle Plugin v2.1.0 here for more info:

http://developer.android.com/tools/revisions/gradle-plugin.html

markdb314
  • 5,735
  • 6
  • 25
  • 26
12

Only solution that worked for me was to disable instant run.

Android Studio -> Preferences -> Build, Execution, Deployment -> Instant Run -> Uncheck 'Enable instant run [...]'

Build went from over 2 minutes to 40 seconds.

Ena
  • 3,481
  • 36
  • 34
  • THANK YOU SO MUCH>> instant run also removes any output apk that was built in the folders too.I was wondering why that was happening – reidisaki May 11 '16 at 17:48
  • This also worked for me. Build time went from ~ 80 seconds to ~12. Guess they still have some kinks to work out. – Cognitio Jul 29 '16 at 22:42
  • 45s to 15s - most efficient optimization i've seen on stackoverflow so far – Azghanvi Sep 01 '17 at 14:38
6

I was facing the same issue and it took me around 10 hours to finally resolve it, so I know your feels.

I googled a lot, I did the same configuration stuff as you did and even if it helped a little, the compiling and running the actual app was still pain in the ass (sometimes it took 2-3 minutes when I changed one line of code, but when I did more work, it usually took 8 minutes and my computer was totally frozen during that time).

But enough talks, lets fix this. What 'app:transformClassesWithDexForDebug' does is that it resolves some dependencies for Dalvik (pre-5.0, api 21) OS versions and what is important - it takes a lot of time. You won't need it for developing, because you can test your app on >= 21, so create separate product flavor for development and release. Here is my gradle build that makes use of it:

apply plugin: 'com.android.application'

final VERSION_MAJOR = 0
final VERSION_MINOR = 0
final VERSION_PATCH = 0
final VERSION_BUILD = 1

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "com.app"
        minSdkVersion 15
        targetSdkVersion 23
        multiDexEnabled true
        versionName "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILD}"
        versionCode VERSION_MAJOR * 10000000 + VERSION_MINOR * 100000 + VERSION_PATCH * 1000 + VERSION_BUILD
    }

    dexOptions {
        incremental = true;
        preDexLibraries = false
        javaMaxHeapSize "2g"
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    productFlavors {
        dev {
            minSdkVersion 21
            applicationId = "com.app.test"
        }
        prod {
            minSdkVersion 15
            applicationId = "com.app" // you don't need it, but can be useful

        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/dependencies.txt'
        exclude 'META-INF/LGPL2.1'
        exclude 'META-INF/ASL2.0'
    }
    lintOptions {
        checkReleaseBuilds false
        abortOnError true
    }

}

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = ['--multi-dex']
        } else {
            dx.additionalParameters += '--multi-dex'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
   ... 
}

Next thing is to make sure you are actually building your app with this build variant. Click on View -> Tool Windows -> Build tools and make sure you have build variant set to 'devDebug'

For some people this might be enough. I found a lot of threads here in SO and also on reddit that ended with this product flavor thing, but this didn't help me at all actually. What helped me is to uprade gradle manually. Since you already tried to do it, I think you are on the right track, but I would suggest using newer gradle version 2.9 which has '40% improved performance' over 2.8.

vanomart
  • 1,739
  • 1
  • 18
  • 39
  • 1
    Thank you for responding vanomart. This seems really promising, however I did not yet get it to work though. It builds the new devDebug flavour, but it's still running that same task. Do I need that afterEvaluate or compileOptions part I see in your build settings? – Justin Hammenga Dec 15 '15 at 13:32
  • you shouldn't need compile options and afterEvaluate. I found out it's not working when you simply download new gradle, you have to properly install it on the system so all the gradle variables are initialized properly. Also if you take a look at .gradle directory in the project, you will see some cached stuff there. Remove everything that is not 2.9. TBH, my builds runs much faster, sometimes takes only couple of seconds, but sometimes is 1-2 minutes again. – vanomart Dec 15 '15 at 13:54
0

That seems like part of the new Instant Run mechanism introduced in Android Studio 2.0 preview, which is responsible to instrument every methods in your app to create execution branch for future code patch. I'm afraid that's why it is extremely slow.

It's weird this task is still taking place even if Instant Run is disabled. I have to downgrade "com.android.tools.build:gradle" to 1.3.0 to avoid that task.

Oasis Feng
  • 7,490
  • 3
  • 31
  • 44
0

Does your application have a database? Does the DB have a big size?

If yes:

  • remove the DB from assets folder (or wherever you keep it) and do a build
  • measure the difference in build times
  • IN MY CASE: it was a dramatic difference from 45 sec down to 15 sec

If No:

  • Monitor Gradle console during incremental builds and see what operation is taking the most time
AlexVPerl
  • 7,652
  • 8
  • 51
  • 83