Application construction speed will directly affect the development efficiency, this article will take you through the transformation of an Android application: “Google Santa Tracker” provides you with ten tips to help you build Gradle faster. When we applied all the tips, the demo app built more than three times faster.

Let’s start with the engineering background of the Google Track Santa app: The app is about 60 megabytes in size, has nine modules,500 + Java files, 1,700 + XML files, 3,500 + PNG image resources, uses Mutil-dex, and has no annotation processor. Second, before we turn on speed up tuning, let’s take a look at the three performance metrics:

  • Full build, that is, restart the debug version of the entire project;
  • Code incremental build, where we modify the Java/Kotlin code of the project;
  • Incremental build of resources refers to the changes we made to the resource files, adding and removing images and strings, etc.

After each tip was implemented, we compared the build times of the above three scenarios as our quantification criteria. Please note that the results of actual operations by developers may differ from those in this article due to different project sizes and development environments.

Tip 1: Use the latest version of the Android Gradle plugin

Every Android Gradle plugin update will fix a lot of bugs and improve performance and other new features, so it is very necessary to keep the latest version of Android Gradle plugin.

Starting with version 3.0, we will distribute the new Android Gradle plugin through Google () ‘s Maven repository, Therefore, we need to add Google () to our repository for the latest plugins (currently, new Projects in Android Studio will have Google () ‘s Maven repository by default).

This is the result of updating the Android Gradle plugin from 2.x to 3.0.0-alpha1. (This demo is based on 3.0.0-alpha1, the performance improvement will be more obvious with the update of the plugin.) The time to build a full application was reduced by 25% directly, incremental builds for code changes were reduced by nearly 40%, and incremental builds for resource changes were reduced by 16%.

Tip 2: Avoid activating older versions of Multidex

This trick should be familiar – avoid activating older versions of Multidex. When the number of application configuration methods exceeds 64K, you need to enable Multidex. When you enable Multidex and the minimum API level of the project is before 21, the older version of Multidex will be activated, which will seriously slow down your build because there is no native support for Multidex at the API level before 21.

Enable multidex developer. The android. Google. Cn/studio/buil…

If you’re building from Android Studio’s Run/debug button, you don’t have to worry about this. Newer versions of Android Studio automatically detect connected devices and emulators, and native Multidex support is provided if the system API level is greater than 21. The minimum API level (minSdkVersion) in the project is also ignored.

Developers who are used to building projects from the command line window should try to avoid this problem by configuring a new productFlavor, setting the minimum API level for the project to 21 or above, and calling assembleDevelopmentDebug from the command line.

The performance improvements were also significant (the gray lines are the initial results), reducing the time by another 5.5 seconds in the full build and more than 50% in the incremental build of code changes, and the incremental build of resource changes took the same amount of time as before.

Tip 3: Disable Multiple APK builds

When an application needs to be published and shipped, we often use a “Multiple APK” build, which can create different versions of the application based on the ABI and pixel density, reduce package size, etc. But this seems redundant at the development stage, so we need to disable the multi-APK build feature to speed up builds.

The multi-APK build ban cannot be set only in the Splits because the Settings are visible to all the build variants in the project. The correct way to disable multiple APK builds is to create a property to do this. Here we set a property called “devBuild” and pass this value to Gradle during the build process. Gradle then sets the Montes.abi. Enable and Montes.density. Enable to false so that it will not generate multiple APKs.

In Android Studio, you can add parameters to the command line by selecting compiler options in the preferences, build, execute, and deployment categories: -PdevBuild, so that Android Studio passes this value to Gradle every time it builds to avoid generating multiple APKs.

As you can see above, this is what happens when I disable multiple APK, and all the metrics continue to decrease.

Multiple APK developer. The android. Google. Cn/Google/play… Build variant developer. The android. Google. Cn/studio/buil…

Tip 4: Minimize resource files

When your application contains a lot of localized resources or special resources for different pixel densities, you may want to apply this trick to speed up the build — minimizing the amount of resources packaged into the application during development.

By default, the build system packages all declared or used resources into APK, but we may only use one of them during development. In this case, we need to use resConfigs() to specify the resources, such as language version and screen pixel density, that will be used to build the development version.

Here we see a significant improvement, with the full build time reduced by another 6 seconds and the incremental build time reduced by more than 20% each.

Tip 5: Disable PNG compression

As with tip 4, this feature itself is quite helpful during the packaging release phase — PNG compression, but disabling this feature during development can improve build efficiency. By default, AAPT compresses project PNG resources to reduce APK size, a process that can take as long as possible depending on the number and size of images.

If you want to avoid using PNG compression, can we mentioned in a tip 3, join in devBuild attribute aaptOptions. CruncherEnabled = false, in the process of building pass this value to gradle, It avoids doing PNG compression.

Another way to avoid compressing PNG is to use images that convert PNGS to WebP. WebP is up to 25% smaller than PNG, and Android Studio 2.3 and up supports pnG-webP conversion directly.

Note that API level 15 and above can support opaque WebP images, while transparent WebP images require API level 18 and above.

As you can see, the full build shaved another 9 seconds off the time. This is also due to the fact that Google Track Santa has over 3,500 PNG images in the app, which takes a lot of time to compress, so the efficiency improvement in this area is significant, while the other incremental builds are just as good as before.

One particular question about the size of APK – when we compared the size of APK with and without PNG compression, we found that the size did not change much, indicating that the PNG images used in the project were fully optimized before being imported and PNG compression was unnecessary.

Tip 6: Use Apply Changes

Starting with Android Studio version 3.5 (currently in the Beta build channel), developers can improve build performance with Apply Changes, which allows Changes to code and resources to take effect directly without restarting the application. Sometimes you don’t even need to restart the current Activity. Unlike Instant Run, Apply Changes takes full advantage of the features of Android 8.0 and later operating systems for runtime detection to dynamically redefine classes. Therefore, if you want to use Apply Changes, you need to have your project running on a real machine or emulator with Android 8.0 (API level 26) or higher.

Tip # 7: Avoid passive change

Us through a small example to illustrate this tip: set the version number as we put the project based on the number of the current time (in fact, you shouldn’t be so operation), the result is each time you build a version number is new, engineering the listing of files will be changed, the results of the last is to slow down the speed of the construction.

As you can see in the figure, we’ve even seen incremental build times double, so try not to add too much nonsense to your build scripts.

This is not a difficult problem to solve, we can determine if there is a devBuild flag in the build script, if so, we can set the version number to a fixed value.

In this example, we purposely included some bad code in the build script to show the damage. As a practical example with Crashlytics, the plugin defaults to adding a unique BUILD ID for each build, which incurs unnecessary time loss. You can avoid this by adding ext.alwaySupDateBuildid = false to your build script, or you can choose to turn off Crashlytics completely during development.

Tip 8: Don’t use dynamic version ids

Gradle provides a very convenient dependency library version number management function, which allows developers to use the latest version of the dependency library by using a plus sign “+”. However, there are several risks to using dynamic builds. From a performance perspective, Gradle checks for updates to dependent libraries every 24 hours. If you have a large number of dependent libraries that dynamically fetch the latest version, this can have an impact on build performance.

Even if you don’t particularly care about these performance losses, it’s still a risk — depending on a library version update, your build is so uncertain that two weeks later you’re building a completely different project because the library code updates aren’t visible to developers.

Tip 9: Gradle memory allocation tuning

The default build environment allocates 1.5 GB of Gradle memory, but this is not suitable for all projects. You need to tune this number to get the best Gradle memory allocation for your project.

At the same time, since Android Gradle 2.1, dex is already in the process by default, so if you set javaMaxHeapSize, you can delete it.

Tip 10: Enable Gradle build cache

Gradle supports build caching for Kotlin projects, which makes building speeds much faster. Gradle build caching is disabled by default. You can enable build caching for everyone by adding the –build-cache parameter to the command line or org.gradle.caching=true to gradle.properties in the project root directory. You can learn more about Gradle build caches in this document.

conclusion

The overall improvement was more than three times faster for full builds and more than 12 times faster for incremental builds of code changes after all the speed boosting tricks were practiced.