Gradle Basics Quiz
BUILD & TOOLING › Gradle
A library module uses Retrofit only inside its own classes and never exposes Retrofit types in its public API. Which configuration should declare Retrofit?
- api, so downstream consumers can also compile against Retrofit types
- implementation, keeping Retrofit an internal, non-transitive detail
- compileOnly, so Retrofit is dropped from runtime packaging and the APK
- runtimeOnly, since Retrofit is only needed once the app is running
Answer: implementation, keeping Retrofit an internal, non-transitive detail
Because Retrofit is an internal detail not exposed in the public API, implementation keeps it off consumers' compile classpath and avoids unnecessary recompilation when it changes.
Module A declares 'api("com.example:widgets:1.0")'. Module B depends on Module A with implementation. What can Module B do?
- Nothing, since api never exposes a dependency to downstream consumers
- Reference com.example.widgets types directly on the compile classpath
- Only reach the widgets types via reflection at runtime, not compile time
- Use the widgets types only within its androidTest source set
Answer: Reference com.example.widgets types directly on the compile classpath
api exposes the dependency transitively, so Module A's consumers, including Module B, get com.example:widgets on their compile classpath and can reference its types directly.
Which statement about compileOnly is correct?
- The dependency is bundled into the final APK and executes at runtime
- The dependency is on the runtime classpath but absent at compile time
- It sits on the compile classpath only and is not packaged in the APK
- It is the default configuration used for ordinary app dependencies
Answer: It sits on the compile classpath only and is not packaged in the APK
compileOnly puts the library on the compile classpath but not the runtime classpath, so it is not packaged into the APK; it is meant for things like annotations or runtime-provided libraries.
In a version catalog, the library alias is written as 'androidx-core-ktx'. What accessor do you use in build.gradle.kts?
- libs.androidx-core-ktx
- libs["androidx-core-ktx"]
- libs.androidxCoreKtx
- libs.androidx.core.ktx
Answer: libs.androidx.core.ktx
Gradle maps dashes (or underscores) in catalog aliases to dots in the generated type-safe accessor, so androidx-core-ktx becomes libs.androidx.core.ktx.
What is the recommended default file and location for a Gradle version catalog in an Android project?
- gradle/libs.versions.toml in the root project's gradle/ folder
- app/versions.gradle inside the app module’s own source folder
- settings.gradle.kts at the project root, right alongside settings
- gradle.properties within each module’s directory holding catalog data
Answer: gradle/libs.versions.toml in the root project's gradle/ folder
Gradle looks for the catalog at gradle/libs.versions.toml by default, and using that name and location enables automatic type-safe accessors with no extra configuration.
How should you apply a plugin that is declared in the version catalog, in a module build.gradle.kts?
- apply(plugin = "com.android.application")
- alias(libs.plugins.android.application)
- id(libs.plugins.android.application)
- implementation(libs.plugins.android.application)
Answer: alias(libs.plugins.android.application)
Plugins that come from the catalog are applied with alias(libs.plugins...); id("...") is reserved for plugins not declared in the catalog, such as convention plugins.
What does Gradle's configuration cache primarily speed up?
- Downloading project dependencies from remote Maven repositories
- Reusing already-compiled task outputs across separate developer machines
- Skipping re-run of the config phase when the build config is unchanged
- Reducing the overall download size of the final packaged APK
Answer: Skipping re-run of the config phase when the build config is unchanged
The configuration cache stores the result of the configuration phase so Gradle can skip re-running build scripts on subsequent builds; reusing task outputs across machines is the separate build cache.
What is a key advantage of writing build files in the Kotlin DSL (build.gradle.kts) over the Groovy DSL (build.gradle)?
- It produces a smaller APK because Kotlin bytecode is more compact.
- It runs the build faster by skipping the configuration phase entirely.
- It provides type-safe syntax, autocomplete, and compile-time checks.
- It is the only DSL that can use version catalogs in Gradle builds.
Answer: It provides type-safe syntax, autocomplete, and compile-time checks.
The Kotlin DSL is statically typed, so Android Studio offers autocomplete and catches errors at edit/compile time; both DSLs build identical artifacts and both support version catalogs.
What is the primary responsibility of settings.gradle.kts?
- Including modules in the build and setting plugin/dependency repos
- Declaring app runtime dependencies with implementation and api entries
- Setting JVM heap size and build cache behavior in the Gradle settings file
- Applying the Android Gradle plugin to every module without per-module config
Answer: Including modules in the build and setting plugin/dependency repos
settings.gradle.kts uses include to register modules and configures pluginManagement and dependencyResolutionManagement repositories; dependencies live in module build files and JVM/cache flags live in gradle.properties.
You want JUnit available only to your local JVM unit tests in src/test, not to instrumented tests or the shipped app. Which configuration should declare it?
- androidTestImplementation
- implementation
- compileOnly
- testImplementation
Answer: testImplementation
testImplementation scopes a dependency to the src/test (local JVM unit test) source set only, so it is excluded from the production app and from the src/androidTest instrumented source set.
Which configuration places a dependency on the runtime classpath but not the compile classpath?
- compileOnly
- runtimeOnly
- implementation
- api
Answer: runtimeOnly
runtimeOnly makes a dependency available at runtime and packages it, but it is not on the compile classpath; compileOnly is the exact opposite, while implementation and api put the dependency on both classpaths.
In the top-level build.gradle.kts you write id("com.android.application") version "8.x" apply false. What does apply false accomplish?
- It disables the plugin for the whole project, so no module can use it
- It applies the plugin only to the root project, leaving subprojects unchanged
- It caches the plugin for faster configuration, but still applies it everywhere
- It pins the plugin version for subprojects, without applying it to the root
Answer: It pins the plugin version for subprojects, without applying it to the root
apply false declares the plugin and locks its version so module build files can apply it without repeating the version, while keeping it unapplied to the root project, which has no Android code to build.
What does a [bundles] entry in gradle/libs.versions.toml let you do?
- Pin transitive dependency versions across the entire build graph
- Declare a plugin entry together with its version in the catalog
- Add several library aliases at once via one type-safe accessor
- Combine two separate version catalogs into one merged catalog
Answer: Add several library aliases at once via one type-safe accessor
A bundle groups several library aliases under one name, so a module can add them all with a single accessor like libs.bundles.compose instead of listing each dependency individually.
Which statement correctly describes Gradle's build cache, as distinct from the configuration cache?
- It reuses task outputs across builds and machines when inputs match
- It caches the configuration phase so build scripts needn't run again
- It stores downloaded artifacts in the local Maven repository
- It keeps the Gradle daemon alive to speed up later builds
Answer: It reuses task outputs across builds and machines when inputs match
The build cache keys task outputs by their inputs and can reuse them locally or remotely across machines; caching the configuration phase is the separate configuration cache, and artifact downloads use Gradle's dependency cache.