Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Demystify and Optimize Your Android Gradle Buil...

Nate Ebel
October 07, 2021

Demystify and Optimize Your Android Gradle Builds - Mobiconf 2021

Gradle and the Android Gradle Plugin are the backbone of most Android projects today. They are also the source of much frustration for dev teams wishing their builds were faster or easier to work with.

This talk aims to demystify your Android build by helping you understand how Gradle works, what happens when you build your project, and how to start optimizing your build for increased developer productivity.

During this talk, we’ll focus on a few key areas including
- The difference between Gradle and Android Gradle Plugin
- What happens when you run a Gradle task
- How to investigate your project’s build performance
- Performance optimizations

By the end of the talk, you should better understand what happens when you build your Android app, and be equipped to start optimizing your builds for faster builds and happier developers.

Nate Ebel

October 07, 2021
Tweet

More Decks by Nate Ebel

Other Decks in Programming

Transcript

  1. Mobiconf 2021 Demystify & Optimize Your Android Gradle Builds Android

    Developer & Instructor Kotlin GDE @n8ebel goobar.dev Nate Ebel
  2. What is Gradle? A. The source of 94.3% of Android

    dev Twitter tra ffi c B. A viable means of heating a small room C. A general purpose build tool used for Android and other projects D. All of the above
  3. What is Gradle? A. The source of 94.3% of Android

    dev Twitter tra ffi c B. A viable means of heating a small room C. A general purpose build tool used for Android and other projects D. All of the above
  4. Android Builds Gradle & the Android Gradle Plugin are the

    backbone of most Android projects today
  5. Developer Productivity Engineering “The use of data analytics and build

    acceleration technologies to speed up critical software development processes - and to make them more e ff i cient.” https://gradle.com/blog/top-three-reasons-to-launch-a-dedicated-developer- productivity-engineering-team/
  6. My hope for you 1. Better understand what happens when

    you build your project 2. Identify at least 1 potential tool or optimization to try out today
  7. Gradle Task “… a single atomic piece of work for

    a build, such as compiling classes or generating javadoc.” https://docs.gradle.org/current/dsl/org.gradle.api.Task.html
  8. Where to Tasks come from? • From Gradle • From

    our own custom Tasks • From Plugins
  9. Custom Gradle Tasks De fi ne your own tasks to

    perform whatever task you need Custom Tasks task clean(type: Delete) { delete rootProject.buildDir } task helloWorld { println("Hello World") }
  10. Gradle Plugins “[… plugins add new tasks, domain objects, conventions,

    and extend core objects…]” https://docs.gradle.org/current/userguide/plugins.html
  11. Custom Gradle Plugins De fi ne your own Gradle plugins

    for common con fi guration or custom tasks Custom Tasks class VersionCodePlugin : Plugin<Project> { override fun apply(project: Project) { project.version = calculateVersion() … } } apply plugin: VersionCodePlugin
  12. First Time Build • Fresh checkout of a project •

    No previously built outputs/artifacts • May pull from a remote cache
  13. Up-To-Date Build • Run a task • Run the same

    task again with no changes • Ideally, nothing should run • Everything should be UP-TO-DATE
  14. Clean Build • Delete local build artifacts • Run your

    task again • May need to rebuild full project • Should ideally pull many artifacts from build cache
  15. Incremental Build • Make a change to your project code/resources

    • Run your task again • Ideally, only a portion of your project should need to rebuild
  16. The Story So Far • Click ‘run app’ • Android

    Studio executes an Android Speci fi c Gradle task • That task comes from Android Gradle Plugin • That task will run via Gradle’s infrastructure • Gradle is designed to avoid doing unnecessary work • Our goal, then, is to con fi gure our builds to do as little work as possible
  17. Gradle Build Output • Build time • Number of tasks

    executed • Number of tasks from cache • Number of tasks up-to-date • Task status
  18. Android Studio Build Analyzer • Build overview • Plugin analysis

    • Task execution time • Warnings & recommendations
  19. Gradle Buildscans • Detailed report of a speci fi c

    build • Easily shareable between team members and across machines • Can extend to fi t the needs of your team
  20. Gradle Buildscans • Con fi guration, Initialization, and Execution time

    • Queryable build timeline • Console outputs • Project structure • Environment details • Cache hit/miss report • Test outputs
  21. How to Generate a Buildscan? • add --scan to the

    end of your Gradle Wrapper invocation • accept the TOS • click the generated link and enter an email • click the link in the email to view your scan • subsequent scans won’t require the email
  22. How can we use a Buildscan? • Analyze con fi

    guration and initialization times to ensure a properly con fi gured build • Analyze task execution to identify slow running tasks • Use the timeline to determine if any cacheable tasks were executed • Diagnose build failures for distributed teammates • Diagnose CI build failures • Identify hardware factors contributing to slow builds
  23. Gradle Enterprise “Gradle Enterprise leverages acceleration technologies to speed up

    the software build and test process and data analytics to make troubleshooting more e ff i cient” https://gradle.com/
  24. What does Gradle Enterprise do? • Store buildscans on remote

    server for historical access and analysis • Automatically store buildscans in a single location • Provides a remote build cache • Analyze build trends over time • Enables support for custom tagging and fi ltering • Supports test distribution and analysis
  25. Gradle Enterprise at Premise • Identify build cache issues across

    local and CI builds • Identify regionally speci fi c build cache issues • Identify build speed regressions due to AGP and NDK • Quickly diagnose build failures for distributed team • Compare buildscans to diagnose build issues
  26. Gradle Enterprise at Premise • Is a paid product •

    Is an incredibly valuable tool for our team
  27. • Parallel execution • Local build cache • Remote build

    cache • Con fi guration cache • File-system watching Build acceleration features
  28. Parallel Execution • Build projects in parallel • Very bene

    fi cial in multi-modular projects with reasonable dependency graph • Add org.gradle.parallel=true to gradle.properties
  29. Gradle Build Cache • Reuse the outputs from previous builds

    even after a clean • Local Cache • Add org.gradle.caching=true to your gradle.properties fi le • Remote Cache • Setup with, or without, Gradle Enterprise
  30. Configuration Caching • Cache con fi guration data • Add

    org.gradle.unsafe.con fi guration-cache=true to gradle.properties • Very experimental / Plugins must support it https://github.com/gradle/gradle/issues/13490
  31. File System Watching • Reduce I/O impact of builds using

    in-memory fi le system info • Add org.gradle.vfs.watch=true to gradle.properties • On by default in Gradle 7+
  32. Optimize memory settings • Allocate more memory to Gradle daemon

    • Add org.gradle.jvmargs=-Xmx2048M to gradle.properties • Allocate more memory to Kotlin compiler • Add -Dkotlin.daemon.jvm.options=-Xmx2048M to gradle.properties • Play with this setting based on your build and hardware
  33. Optimize memory settings • Remember that builds run in environments

    with limited resources • (Gradle daemon + Kotlinc) * numberOfSeparateBuildProcesses = total memory • Your machine, your teammate’s machine, and your CI machine might di ff er
  34. Optimize how you build • Use a single JDK •

    Keep libraries and tooling up to date • Build only what is needed • Modularize your project • Reduce the use of kapt
  35. Use the same JDK • Use the same JDK for

    Android Studio and command line builds • Set JAVA_HOME environment variable • Con fi gure Android Studio to use that JDK rather than embedded • This will speed up builds when switching from cmd line & Android Studio
  36. Keep libraries up-to-date • Stay up to date with libraries,

    plugins, languages • Helps pick up performance improvements, cache miss fi xes, etc
  37. Build only what is needed • Don’t minify your app

    if you don’t need to • Don’t build multiple variants if you don’t need them all • Exclude locales/resources for dev builds when not needed • Disable plugins such as Crashlytics if not needed for dev builds • Build/test/analyze in parallel when possible
  38. Modularize your project • Modules/projects can build in parallel •

    Splitting your project into smaller modules enables greater parallelization • Limited bene fi t when most of the code is all in a single module • Limited bene fi t if all modules are highly coupled
  39. Reduce the use of kapt • Kapt is very slow

    for Kotlin builds • Avoid annotation processors with kapt if possible • Limit to speci fi c modules if possible • Consider using KSP if applicable for your project
  40. Gradle Doctor • Plugin to diagnose & prevent common build

    issues • Con fi gurable warnings for things such as • Build speed issues • Annotation processing time • Mismatched JDK versions • Building all variants • Remote cache speed issues https://runningcode.github.io/gradle-doctor/
  41. android-gradle-cache-fix Plugin • Plugin to fi x known build cache

    issues in Android Gradle Plugin • Add to your project and start seeing more cache hits https://github.com/gradle/android-cache- fi x-gradle-plugin
  42. Gradle Profiler • Run multiple Gradle builds and aggregate the

    results • Highlights statistically signi fi cant changes to build performance • Use to pro fi le the impact of build changes such as enabling caching • Can be run manually or automated for common scenarios https://github.com/gradle/gradle-pro fi ler
  43. Keep your project up-to-date • Stay up to date with

    libraries, plugins, languages • Helps pick up performance improvements, cache miss fi xes, etc
  44. To speed up our builds, we can use faster hardware,

    do less intensive work, or do less work.