I have a big Android Studio project that has a separate module which contains native code.
The native build is defined with CMake and includes a bunch of source files of C++ code.
I noticed that since a very recent update (might be Android Studio 3.5), NDK rebuilds everything ALL THE TIME.
It can happen with a small change in Java code, switching flavor in an unrelated module in the project, incrementing version code, etc.
This is a major problem, since it can waste 10 minutes at a time for no reason.
I could not find a reasonable way to profile NDK builds in Android Studio and check what's causing the rebuild or what's taking so long.
Unfortunately the project's build files are too big to attach here. Any pointers for things to look after?
For the C/C++ code that you build with cmake, make sure you point cmake to a directory where it can keep its object files and binary outputs.
Let's say you have a dependency on Game in your top level CMakeLists.txt like so:
# dependency: Game
set ( game_src_DIR ../Game )
add_subdirectory( ${game_src_DIR} ${CMAKE_CURRENT_BINARY_DIR}/game )
Then the second parameter to add_subdirectory specified the place where AndroidStudio will keep the object files.
The debug and release object files will live in different subdirs, as will each dependency, so switching debug/release will not clash.
This appears to have been a regression in behavior from Android Studio 3.4 and has been fixed in Android Studio 4.1 Canary 4. Release notes are here.
Often, it helps to split the AS project such that the C++ part, possibly with its Java wrappers become a separate (library) module. This module will hopefully be more stable, not sensitive to increments of app version code.
Such module should not define many flavors, but have careful matching to the flavors of other modules. Sometimes, it makes sense even to disable "debug" variants for such library. There was an effort of the NDK team to better handle debug vs. release build switching, but this is still tricky.
But if after these improvements, insignificant changes to the project still cause massive rebuild, I would suggest to consider ccache.
I am using android studio v 3.1. Operating System - Windows 10. Core i5 with 16 GB ram.
Below is the result of build profiling
:app:transformClassesWithDesugarForDevelopmentQuickbuild 35.137s
:app:compileDevelopmentQuickbuildJavaWithJavac 31.917s
:app:transformClassesWithDexBuilderForDevelopmentQuickbuild 28.579s
:app:compileDevelopmentQuickbuildKotlin 20.145s
:app:transformClassesWithMultidexlistForDevelopmentQuickbuild 16.873s
:app:mergeDevelopmentQuickbuildResources 16.363s
:app:transformResourcesWithMergeJavaResForDevelopmentQuickbuild 7.958s
:app:transformNativeLibsWithMergeJniLibsForDevelopmentQuickbuild 6.483s
:app:processDevelopmentQuickbuildResources 4.835s
Projects gradle.properties has below configuration
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.daemon=true
android.enableBuildCache=true
kotlin.incremental=true
still for any single line of change build takes at least 2.3 minutes. This problem occurs only in windows and on ubuntu same configuration takes 15-20 seconds.
What else can be done to reduce build time?
In (Android Studio 3.1) in gradle.properties add these 2 lines :-
android.enableD8.desugaring=true
android.enableD8=true
Also for multidexing you can add
multiDexEnabled true
to defaultConfig
I wrote below all the usual tricks.
Also in my machines the Windows versus Linux gradle battle is won by the Linux. However increasing the heap size, may help you get closer to your ubuntu compile time.
Increase the heap size
Starting from the Android Studio 2.0, all dex in the process runs in a single VM and that VM is also shared with the gradle. This requires more memory to accommodate all toghther.
By default, the heap size under Windows is 1GB. You have to increase the heap size. The more RAM you have the more you can use.
For an 8Gb RAM developper machine
i found that a 3GB heap size is best choice. For your 16GB machine you are free to experiment with a much more bigger heap size.
How to do it?
Add the line below to your gradle.properties:
org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Parallelise build
(I saw you already did it, but i mention here for anybody else to read.)
If you have multiple modules in you project, allow gradle to build your project in parallel.
How to do it?
Add the line below to your gradle.properties:
org.gradle.parallel=true
Configure on demand
(I saw you already did it, but i mention here for anybody else to read.)
Gradle provides — configure-on-demand flag that will tell gradle to only build the components that it really needs.
Basically, it tells Gradle to configure modules that are only relevant to the requested tasks instead of configuring all of them.
This setting is usually relevant for multiple modules projects but notice libraries your project may also benefit for using this flag.
For example Google I/O app has two components Android (contains the source code related to the android application) and Server (contains code related to backend server). With default graddle settings they are both configured when compilling.
How to do it?
Add the line below to your gradle.properties:
org.gradle.configureondemand=true
... or access Preferences > Build, Execution, Deployment > Compiler and check configure on demand option.
Enable Gradle daemon
(I saw you already did it, but i mention here for anybody else to read.)
Gradle runs on the Java Virtual Machine (JVM) and uses several supporting libraries that require a non-trivial initialization time. As a result, it can sometimes seem a little slow to start. The solution to this problem is the Gradle Daemon: a long-lived background process that executes your builds much more quickly than would otherwise be the case.
You won’t be able to see the time difference in your first build, but build time will decrease in subsequent builds AFTER gradle daemon is initialised.
If you are using the gradle version 3.0 or above, the gradle daemon is by default enabled. If you are running on older versions it's not.
How to do it?
Add the line below to your gradle.properties:
org.gradle.daemon=true
I've recently ran into this problem, and would like to know, if possible, whether there's a solution for it.
Basically in the project I'm currently working, there used to be some legacy class files that were deleted in a past commit, but sometimes I need to look them up for quick reference, so I just reverted them back to my local changelist and set them as unversioned.
Now, the problem is that due to the legacy nature of these files, some of them don't compile anymore, but the gradle build attempts to compile them although they're unversioned.
So, my question here is: Is there a way to make gradle ignore unversioned files, just stop contemplating them for the build?
No, there is no such way. Gradle cannot exclude files from build based on their version control status. If you only need to use those classes for reference, move them to a directory outside of your project root directory.
Since the last update (Build from june 25) any changes in the Android studio Gradle is painfully slow. And it also seems to autotrack changes when you edit the file and recompile on keyup.
Each change takes several minutes on my i5.
Any idea how I can speed up my Gradle changes?
Definitely makes a difference: How To… Speed up Gradle build time
Just create a file named gradle.properties in the following directory:
/home/<username>/.gradle/ (Linux)
/Users/<username>/.gradle/ (Mac)
C:\Users\<username>\.gradle (Windows)
Add this line to the file:
org.gradle.daemon=true
After change this settings my compile time 10 mins reduced to 10 secs.
Step 1:
Settings(ctrl+Alt+S) ->
Build,Execution,Deployment ->
Compiler ->
type "--offline" in command-line Options box.
Step 2:
check the “Compile independent modules in parallel” checkbox.
& click Apply -> OK
Step 3: In your gradle.properties file -> Add following lines
org.gradle.jvmargs=-Xmx2048M -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.daemon=true
Update:
If you are using Android studio 2.0 or above try the Instant Run
Settings → Build, Execution, Deployment → Instant Run → Enable Instant
Run.
More info about Instant Run - https://developer.android.com/studio/run/index.html#instant-run
I was able to reduce my gradle build from 43 seconds down to 25 seconds on my old core2duo laptop (running linux mint) by adding the following to the gradle.properties file in android studio
org.gradle.parallel=true
org.gradle.daemon=true
source on why the daemon setting makes builds faster:
https://www.timroes.de/2013/09/12/speed-up-gradle/
The dev are working on it. Like I posted in this answer the fastest solution right now is to use gradle from the command line and you should switch to binary libs for all modules you do not develop. On g+ there is a discussion with the developers about it.
Following the steps will make it 10 times faster and reduce build time 90%
First create a file named gradle.properties in the following directory:
/home/<username>/.gradle/ (Linux)
/Users/<username>/.gradle/ (Mac)
C:\Users\<username>\.gradle (Windows)
Add this line to the file:
org.gradle.daemon=true
org.gradle.parallel=true
And check this options in Android Studio
There is a newer version of gradle (ver 2.4).
You can set this for your project(s) by opening up 'Project Structure' dialog from File menu,
Project Structure -> Project -> Gradle version
and set it to '2.4'.
You can read more about boosting performance at this link.
This is what I did and my gradle build speed improved dramatically! from 1 min to 20sec for the first build and succeeding builds became from 40 sec to 5 sec.
In the gradle.properties file
Add this:
org.gradle.jvmargs=-Xmx8192M -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
In the Command Line Arguments via Go to File > Other Settings> default Settings >Build, Execution, Deploy> Complier and add the following arguments to Command Line Arguments
Add this:
--debug --stacktrace -a, --no-rebuild -q, --quiet --offline
With Android Studio 2.1 you can enable "Dex In Process" for faster app builds.
You can get more info about it here: https://medium.com/google-developers/faster-android-studio-builds-with-dex-in-process-5988ed8aa37e#.vijksflyn
Try to avoid using a Mac/PC that has only 8 GB of RAM when doing Android development. As soon as you launch even 1 emulator (Genymotion or otherwise), your build times become extremely slow in Android Studio with gradle builds. This happens even if you make a simple one-line change to 1 source file.
Closing the emulator and using a real device helps a lot, but of course this is very limiting and less flexible. Reducing the RAM usage setting of the emulator can help, but the best way is to ensure your laptop has at least 12-16 GB of RAM.
Update (June 2017): There are now several good medium.com articles that explain how to speed up Android Studio gradle builds in detail, and it even works on 8 GB machines:
How to decrease your Gradle build time by 65%:
https://medium.com/#kevalpatel2106/how-to-decrease-your-gradle-build-time-by-65-310b572b0c43
Make your Gradle builds fast again!: https://medium.com/#wasyl/make-your-gradle-builds-fast-again-ea323ce6a435
The summarised consensus is:
Create a gradle.properties file (either global at ~/.gradle/gradle.properties or local to project), and add the following lines:
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.configureondemand=true
dexOptions {
incremental true
javaMaxHeapSize "4g"
}
Enable Offline Work
Improve Gradle Performance by adding following code in gradle.properties
org.gradle.daemon=true
org.gradle.parallel=true
Step by step guide:http://www.viralandroid.com/2015/08/how-to-make-android-studio-fast.html
Acording to this page of the Android Team of Wikimedia Apps, a good way of optimize Gradle builds is adding this lines to your ~/.gradle/gradle.properties
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx2048M
For those who do not have the file there are two ways to do it:
Add the file locally in your project by creating a file called gradle.properties in the project root or,
You can set them globally for all your projects by creating the same file in your home directory (%UserProfile%.gradle on Windows, ~/.gradle on Linux and Mac OS X)
It is a good practice to set the properties in your home directory, rather than on a project level.
You can also use command line for better performance.You can use the command ./gradlew <task name> from inside the root folder of your project from linux or use gradlew.bat file like gradlew <task name>.when you first run one of the commands above for a given Gradle version, it will download the corresponding Gradle distribution and use it to execute the build.
When importing a Gradle project via its wrapper, your IDE may ask to use the Gradle 'all' distribution. This is perfectly fine and helps the IDE provide code completion for the build files.
Not only does this mean that you don’t have to manually install Gradle yourself, but you are also sure to use the version of Gradle that the build is designed for. This makes your historical builds more reliable.
for more info refer Executing a build with the Wrapper
For faster builds, increase the maximum heap size for the Gradle daemon to more than 2048 MB.
To do this set org.gradle.jvmargs=-Xmx2048M in the project gradle.properties.
Add this to your gradle.properties file
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx2048M
Add a build.gradle file:
android {
...
dexOptions {
javaMaxHeapSize "4g" //specify the heap size for the dex process
}
...
}
I hope it helps.
I’m running a 5th gen i7 with Windows 10 and a 1TB Solid State.
I compressed the Android Studio Projects folder and got about an 80% boost.
Hope this helps.
I then combined it with the above solutions ie (org.gradle.parallel=true, org.gradle.daemon=true). The performance boost was quite impressive.
Additionally:
All of the above answers are totally correct but I must state as an experience Android developer (of 4 and a half years) that: No Android/Gradle developer should be working on a machine with a spinner drive, you need to fork out for a Solid State. We all hit that play button in the IDE 100s of times per day. When I went from a spinner to SSD (post Gradle), my speed and efficiency was literally 2 – 4 times faster and I promise you I’m NOT exaggerating here.
Now I’m not talking about having a machine with a small SSD and a big spinner, I’m talking about 1 big SSD. If you already have a machine with a small SSD and a big spinner you can upgrade the small spinner to say a 500GB SSD and set the SSD as your main OS drive with your developer tools installed on it.
So if you’re working in a fast paced environment please show this post to your boss. A decent 1TB SSD will set you back about £300 (including VAT), or about £160 for a 500GB SSD. Depending on if you are a junior or senior Android developer the drive will pay for itself (in wages expenses) in 1 – 2 working weeks, or about 2 and a half to 5 working days if you invest in a smaller; say 500GB SSD.
A lot of developers may argue that this is not the case, but it is the case for Gradle, as the Gradle system is very hard on the direct disk access. If you work with .NET/C#/VB Net or other development tools you won’t notice much difference but the difference in Gradle is HUGE. If you act on this post I promise you, you won’t be disappointed. Personally I’m using fifth gen i7 with 8GB RAM which originally came with a 1TB Spinner and I upgraded it to a Samsung SSD 840 EVO 1TB and I’ve never looked back since. I bought mine from: https://www.aria.co.uk.
Hope this helps. Also I must state that this is NOT a commercially motivated post, I’m just recommending Aria as I’ve used them many times before and they’ve always been reliable.
few commands we can add to the gradle.properties file:
org.gradle.configureondemand=true - This command will tell gradle to only build the projects that it really needs to build.
Use Daemon — org.gradle.daemon=true - Daemon keeps the instance of the gradle up and running in the background even after your build finishes. This will remove the time required to initialize the gradle and decrease your build timing significantly.
org.gradle.parallel=true - Allow gradle to build your project in parallel. If you have multiple modules in you project, then by enabling this, gradle can run build operations for independent modules parallelly.
Increase Heap Size — org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - Since android studio 2.0, gradle uses dex in the process to decrease the build timings for the project. Generally, while building the applications, multiple dx processes runs on different VM instances. But starting from the Android Studio 2.0, all these dx processes runs in the single VM and that VM is also shared with the gradle. This decreases the build time significantly as all the dex process runs on the same VM instances. But this requires larger memory to accommodate all the dex processes and gradle. That means you need to increase the heap size required by the gradle daemon. By default, the heap size for the daemon is about 1GB.
Ensure that dynamic dependency is not used. i.e. do not use
implementation 'com.android.support:appcompat-v7:27.0.+'.
This command means gradle will go online and check for the latest version every time it builds the app.
Instead use fixed versions i.e. 'com.android.support:appcompat-v7:27.0.2'
Open gradle.properties from android folder and uncomment highlighted lines and provide memory values as per your machine configuration.
I have 8gb ram on my machine so I gave maximum 4096mb and 1024mb respectively.
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
//Uncomment below line for providing your system specific configuration
#org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError - Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
#http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
//Uncomment below line to allow parallel process execution.
#org.gradle.parallel=true
My build time was reduced to half after this.
Happy building!!
It often happens when you enabled multidex in you project. This can potentially slow your development process!!
According doc:
multidex configuration requires significantly increased build processing time because the build system must make complex decisions about which classes must be included in the primary DEX file and which classes can be included in secondary DEX files. This means that incremental builds using multidex typically take longer and can potentially slow your development process.
but you can optimize this:
To mitigate longer incremental build times, you should use pre-dexing to reuse multidex output between builds.
If you're using Android Studio 2.3 and higher, the IDE automatically uses this feature when deploying your app to a device running Android 5.0 (API level 21) or higher.
So you need to set the minSdkVersion to 21 or higher!
But if you production version need to support minSdkVersion lower than 21, for example 19
you can use productFlavors to set minSdkVersion 21 for you dev version:
android {
defaultConfig {
...
multiDexEnabled true
// The default minimum API level you want to support.
minSdkVersion 15
}
productFlavors {
// Includes settings you want to keep only while developing your app.
dev{
//the IDE automatically uses pre-dexing feature to mitigate longer incremental when deploying your app to a device running Android 5.0 !
minSdkVersion 21
}
prod {
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.android.support:multidex:1.0.3'
}
I do prefer building from command line for better build times. If your app code base is large and you have multiple modules then you can try Local AAR approach as described here, it will give you a big boost in Android Studio performance & gradle build times. Its compatible with command line builds as well
https://blog.gojekengineering.com/how-we-improved-performance-and-build-times-in-android-studio-306028166b79
Demo project with integration instructions can be found here: https://github.com/akhgupta/AndroidLocalMavenRepoAARDemo
Right click on Drawable folder and convert png/jpg images to webp format it improved the gradle significantly
From the android developer doc:
Configure JVM garbage collector. It reduced the build time to 2 to 4 seconds
gradle.properties file
org.gradle.jvmargs=-Xmx1536m -XX:+UseParallelGC
Refer to this Developer doc
Follow Android Studio and Gradle performance guidelines
Optimize your build speed
Improving the Performance of Gradle Builds
Configuration cache
Build Cache
Overall
Always keep Gradle version up-to-date to receive new performance improvements
Modularize your project as much as possible to benefit from Gradle parallel work
Know Gradle properties and understand what they do
I have recently migrated to new Android Studio 2.2 among many other features I also came across android.enableBuildCache=true to decrease build time.
My question is that how is this helping my builds go faster and what exactly is being cached ? Because I have actually noticed an increase in initial build time which has made me question whether I should use it or not. If somebody could explain me the inner functionality and what exactly is cached and in what conditions then maybe I will be able to fine tune this caching and speed up my builds.
this link shows all the details: http://tools.android.com/tech-docs/build-cache
here are some relevant parts:
... build cache feature that can speed up build times (including full
builds, incremental builds, and instant run) by storing and reusing
files/directories that were created in previous builds of the same or
different Android project.
Currently, the build cache contains only pre-dexed libraries; in the
future, we will use it for caching other types of files as well.
when your build time increased, then maybe
I guess this could be normal for the first build after activating the cache
it's a bug of this experimental feature: in this case, please file a bug
the cache was not used at all:
Step 0
Ensure that android.dexOptions.preDexLibraries is either not
set or set to true; otherwise the libraries will not be pre-dexed and
therefore the build cache will not be used.
Step 1
android.enableBuildCache=true
Step 2
Build your Android project and check the following locations to see whether the build cache took
effect. By default the cache-dir is
/.android/build-cache. The final pre-dexed files
are stored in
/build/intermediates/pre-dexed/debug and
/build/intermediates/pre-dexed/release. You
need to run the command line to see the “pre-dexed” directory; if you
click the “Run” button from the Android Studio menu, you will not see
this directory as it will be deleted.
Note: If you are using Multi-dex with minSdk >= 21, the dexed files
will be stored directly into the
/build/intermediates/transforms/dex directory
without being stored in /build/intermediates/pre-dexed.