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

Cache Me If You Can

Avatar for RyuNen344 RyuNen344
September 11, 2025

Cache Me If You Can

DroidKaigi 2025

Avatar for RyuNen344

RyuNen344

September 11, 2025
Tweet

More Decks by RyuNen344

Other Decks in Programming

Transcript

  1. Agendas 1. Today's Goals 2. Why Gradle? How the Android

    Gradle Plugin works? 3. Lifecycle and Lifecycle-aware, everywhere 4. Cache of Gradle 5. Faster, Faster, Faster 6. Key Takeaways
  2. Today’s Goal • Understands basic concepts of Gradle • Taming

    Android Gradle Plugin → The ABCs of Faster Gradle Builds
  3. Project and Task • Extension as Gradle Plugin • Several

    Language Support by Of fi cial Gradle Plugin • C++, Swift and multiple JVM based languages C++
  4. Easy to cache • Gradle watches Task inputs/outputs • Developer

    just de fi ne deterministic input and Gradle Task action
  5. How AGP? :app:assembleDebug +--- :app:mergeDebugNativeDebugMetadata | \--- :app:preDebugBuild | \---

    :app:preBuild \--- :app:packageDebug +--- :app:compileDebugJavaWithJavac +--- :app:compressDebugAssets +--- :app:l8DexDesugarLibDebug +--- :app:mergeDebugAssets * +--- :app:mergeDebugJavaResource +--- :app:mergeExtDexDebug +--- :app:mergeLibDexDebug +--- :app:mergeProjectDexDebug +--- :app:preDebugBuild * +--- :app:processDebugManifestForPackage +--- :app:processDebugResources * +--- :app:stripDebugDebugSymbols +--- :app:validateSigningDebug +--- :app:writeDebugAppMetadata \--- :app:writeDebugSigningConfigVersions • Assemble task depends on many tasks
  6. How AGP? :app:assembleDebug +--- :app:mergeDebugNativeDebugMetadata | \--- :app:preDebugBuild | \---

    :app:preBuild \--- :app:packageDebug +--- :app:compileDebugJavaWithJavac +--- :app:compressDebugAssets +--- :app:l8DexDesugarLibDebug +--- :app:mergeDebugAssets * +--- :app:mergeDebugJavaResource +--- :app:mergeExtDexDebug +--- :app:mergeLibDexDebug +--- :app:mergeProjectDexDebug +--- :app:preDebugBuild * +--- :app:processDebugManifestForPackage +--- :app:processDebugResources * +--- :app:stripDebugDebugSymbols +--- :app:validateSigningDebug +--- :app:writeDebugAppMetadata \--- :app:writeDebugSigningConfigVersions • Assemble task depends on many tasks • AGP tells Gradle what the inputs and output of the Assemble task
  7. How AGP? :app:assembleDebug +--- :app:mergeDebugNativeDebugMetadata | \--- :app:preDebugBuild | \---

    :app:preBuild \--- :app:packageDebug +--- :app:compileDebugJavaWithJavac +--- :app:compressDebugAssets +--- :app:l8DexDesugarLibDebug +--- :app:mergeDebugAssets * +--- :app:mergeDebugJavaResource +--- :app:mergeExtDexDebug +--- :app:mergeLibDexDebug +--- :app:mergeProjectDexDebug +--- :app:preDebugBuild * +--- :app:processDebugManifestForPackage +--- :app:processDebugResources * +--- :app:stripDebugDebugSymbols +--- :app:validateSigningDebug +--- :app:writeDebugAppMetadata \--- :app:writeDebugSigningConfigVersions • Assemble task depends on many tasks • AGP tells Gradle what the inputs and output of the Assemble task When and Where does AGP tell that to Gradle?
  8. Initialization Phase • Read settings.gradle and recognize project structure •

    Specify dependency resolution strategies • Apply settings plugin
  9. Con fi guration Phase • Read project’s build.gradle • Apply

    plugin to project • plugin creates con fi guration and tasks • Resolve dependencies • Graph resolution phase • Artifact resolution phase • Execute build scripts
  10. Execution Phase • Execute tasks • Determine which tasks to

    execute by the task execution graphs • UP-TO-DATE and FROM-CACHE mean that Gradle has skipped a task by using incremental builds or the build cache
  11. AGP's Lifecycle • In old Variant API could make a

    variant disabled after creation • This can break the Task Graph(DAG) • It’s not good for Build Cache(even Con fi guration Cache)
  12. Wrap-up Part 1 • Gradle has a lifecycle • Gradle

    manages task dependencies and forms a DAG • Gradle reuses task results based on task input/output • Android Gradle Plugin also has a lifecycle • Recent API changes in AGP are to conform to Gradle's lifecycle • Old Variant API is scheduled to be deprecated in AGP 9.0.0, removed in 10.0.0, so it's recommended to migrate to the new API now
  13. Before We Get to the Cache of Gradle • Idempotence

    • same input must produce the same output • Performance • appropriate granularity of cache makes high cache hit rate • cache hit is faster than re-execution
  14. Cache of Gradle : FROM-CACHE • Based on: • Hash

    of the task implementation class • All declared inputs • Task Identi fi er • Normalized content hash of fi le inputs used as fi ngerprint • build script is also included in key calculations (e.g. `doFirst`, `doLast`) • Env and System Props will not include unless explicitly declared as input
  15. Cache of Gradle : Reusing con fi guration cache •

    Based on: • GRADLE_USER_HOME • init script • included build scripts • Custom Value Source • System Property and environment • etc… • Requirements: • implements java.io.Serializable
  16. Wrap-up Part 2 • Incremental build and Build cache •

    re-use task results based on task input/output • Con fi guration cache • re-use task graph based on con fi guration inputs • Gradle uses different scopes and targets of cache to speed up builds in multiple ways • Con fi guration Cache became the preferred execution mode • Update your API to prevent issues, same as AndroidComponents API
  17. Make input/output more deterministic • De fi ne @Input and

    @Output • To enable incremental builds, de fi ne an output property even for tasks that don’t have output • Use Gradle Provider or Property API, instead of Primitive class
  18. Make input/output more deterministic • When inputs have changed, outputs

    must change • Avoid using non-declared inputs (Do not use Env or system prop inside TaskAction) •Annotate with @CacheableTask
  19. Make input/output more deterministic • Avoid using random value as

    inputs • Use abstracted fi le paths so that the cache does not depend on the environment • Do not edit task output in build script
  20. Make con fi guration more deterministic • Can't build project,

    after adding `org.gradle.con fi guration- cache=true` 😇
  21. Make con fi guration more deterministic • Do not use

    `afterEvaluate` block • `afterEvaluate` block executes after con fi guration phase • `afterEvaluate` can break con fi guration phase result
  22. Make con fi guration more deterministic • Do not touch

    non- serializable objects in execution time
  23. Make con fi guration more deterministic • Use `ProjectLayout` or

    `BuildLayout` API to access fi les instead of `project` • Use injected `{FileSystem| Archive|Exec}`Operations to access fi les instead of `project`
  24. Make con fi guration more deterministic • Use `ProviderFactory` API

    to access environment variables, system properties, external process results instead of `System` or direct execution
  25. Optimize project structure • Android app developer needs fast build

    1. Adoption of Jetpack Compose 2. Multi-module as a prerequisite
  26. Optimize project structure 1.Remove redundant Gradle plugin from sub-project 2.Remove

    redundant dependency (library or project) 3.Do not con fi gure build variant/project fl avor on library module, use DI
  27. Use Build Scan® • Gradle Knows Gradle Better Than You

    Know about Gradle • Visualize parallelism on Web UI
  28. Use Develocity® Plugin • You can visualize without metadata publication

    • Visualize parallelism on IntelliJ and Android Studio
  29. Key Takeaways • Gradle has a lifecycle, AGP also has

    a lifecycle • Gradle has different scopes and targets of cache to speed up builds in multiple ways • Make input/output/con fi gurations more deterministic • Use Gradle's provided APIs instead of `project` or `System` • Modify artifacts through AndroidComponents API • Optimize project structure to reduce re-compilation scope and increase parallelism • Use Build Scan and Develocity Plugin
  30. About Me • Bunjiro Miyoshi (id: RyuNen344) • KMPΛֶΜͩΒͳ͔ͥGradleͷ஌͕ࣝ૿͑ͨ •

    Kodee͘Μݟ͔͚ͨΒͥͻ #KodeeEverywhere ͷϋογϡλάΛ͚ͭͯᄁ͖Λʂ
  31. Q. What’s next ? A. Lazy Con fi guration •

    Gradle 8.14.3 : Con fi gurations are initialized lazily • https://docs.gradle.org/8.14.3/ release- notes.html#con fi gurations-are- initialized-lazily • AGP 8.12.0 supports lazy con fi guration • https://issuetracker.google.com/ issues/416349489
  32. Q. What’s next ? A. Isolated Projects • https://docs.gradle.org/current/userguide/isolated_projects.html •

    Isolated Projects extends the con fi guration cache • the con fi guration model of Gradle projects are "isolated" from each other • Make con fi guration cache more immutable • Make con fi guration cache safely run in parallel
  33. Improvements of o ff i cial documents • JetBrains -

    Working with Gradle • https://www.jetbrains.com/guide/java/tutorials/working-with-gradle/ • Android Developers - Con fi gure your build • https://developer.android.com/studio/build • Android Developers - Write Gradle plugins • https://developer.android.com/build/extend-agp • Gradle - Improve the Performance of Gradle Builds • https://docs.gradle.org/current/userguide/performance.html • Gradle - Cookbook • https://cookbook.gradle.org/
  34. EOF