Build Variants & Signing Quiz
BUILD & TOOLING › Gradle
An app declares flavor dimensions ["tier", "env"] with flavors free/paid (tier) and dev/prod (env), plus build types debug and release. How many build variants are produced?
- 4
- 6
- 8
- 12
Answer: 8
Variants = product of flavors per dimension times build types: 2 (tier) x 2 (env) x 2 (build types) = 8.
For the fullRelease variant, which source set has the HIGHEST merge priority?
- src/main is the common source set and merges later
- src/release is the build-type source set with lower priority
- src/full is the flavor source set, not the top one
- src/fullRelease has the highest merge priority
Answer: src/fullRelease has the highest merge priority
The variant-specific source set src/fullRelease wins over the build type (src/release), the flavor (src/full), and src/main.
You need a String FEATURE_FLAG readable in Kotlin code that differs per build type. Which Gradle DSL is correct?
- resValue("string", "FEATURE_FLAG", "true") // defines a resource, not BuildConfig
- buildConfigField("String", "FEATURE_FLAG", "\"true\"")
- manifestPlaceholders["FEATURE_FLAG"] = "true" // only substitutes manifest values
- applicationIdSuffix = ".true" // changes the app ID, not a code constant
Answer: buildConfigField("String", "FEATURE_FLAG", "\"true\"")
buildConfigField emits a typed constant on the generated BuildConfig class readable from code; the String literal must be quoted inside the value. resValue produces a resource, not a BuildConfig field.
Under Play App Signing, which statement about the two keys is correct?
- Google holds the app signing key; you sign uploads with the upload key.
- You hold both keys yourself, and Google never gets either one.
- Google holds the upload key, while you keep the app signing key.
- The upload key and app signing key are the same key in Play App Signing.
Answer: Google holds the app signing key; you sign uploads with the upload key.
With Play App Signing you sign uploads with your upload key, and Google re-signs the distributed APKs with the app signing key it securely stores. They should be different keys.
A debug build of your app installs alongside the release build on the same device without conflict. Which configuration most directly enables this?
- isMinifyEnabled = true on the release build type for shrinking
- versionNameSuffix = "-debug" on the debug build type only
- applicationIdSuffix = ".debug" on the debug build type
- signingConfig set on the debug build type for signing the APK
Answer: applicationIdSuffix = ".debug" on the debug build type
Two apps can coexist only if their applicationId values differ; applicationIdSuffix changes the installed package id. versionNameSuffix only affects the displayed version string.
Your app defines a build type 'staging' that a library dependency does not have. What resolves the variant-matching failure?
- missingDimensionStrategy("staging", "debug", "release")
- initWith(getByName("debug")) to copy the debug build type
- matchingFallbacks += listOf("debug", "release")
- flavorDimensions += listOf("staging", "debug")
Answer: matchingFallbacks += listOf("debug", "release")
matchingFallbacks tells Gradle which of the library's build types to fall back to when the app has a build type the library lacks. missingDimensionStrategy is for missing flavor dimensions, not build types.
Which statement about the local debug keystore is TRUE?
- Auto-created at $HOME/.android/debug.keystore; unfit for Play releases
- It must be manually generated by you before the first debug build
- Google Play readily accepts app uploads signed only with the debug keystore
- It is a prerequisite for enabling Play App Signing on your app
Answer: Auto-created at $HOME/.android/debug.keystore; unfit for Play releases
The debug keystore is generated automatically with known credentials at $HOME/.android/debug.keystore for local testing; Play and most stores reject debug-signed apps.
You add buildConfigField("String", "API_URL", "\"https://x\"") to a module built with AGP 8.x, but the generated BuildConfig class is missing. What is the most likely cause?
- BuildConfig is generated only for the release build type and never debug
- Since AGP 8.0, BuildConfig isn't generated without buildConfig = true
- buildConfigField requires the string value to be passed without quotes
- You must first enable the android.nonTransitiveRClass flag
Answer: Since AGP 8.0, BuildConfig isn't generated without buildConfig = true
Starting with AGP 8.0 the BuildConfig class is no longer generated by default; you must opt in per module with buildFeatures { buildConfig = true } (or the matching gradle.properties flag).
flavorDimensions = listOf("tier", "env") with flavors paid (tier) and prod (env). Which Gradle task assembles the paid + prod + release variant?
- assemblePaidProdRelease
- assembleReleaseProdPaid
- assembleProdPaidRelease
- assembleRelease
Answer: assemblePaidProdRelease
Variant task names are assemble<Flavors><BuildType> with flavors ordered by their dimension declaration order (tier then env) and the build type capitalized last, giving assemblePaidProdRelease.
A library you depend on declares a flavor dimension that your own app module does not define, causing a variant-matching failure. What resolves it?
- Add matchingFallbacks for the missing dimension
- Add the library's dimension to your flavorDimensions list
- Use initWith to copy the library flavor
- missingDimensionStrategy("<dimension>", "<flavor>")
Answer: missingDimensionStrategy("<dimension>", "<flavor>")
missingDimensionStrategy tells Gradle which flavor to pick for a dimension that a dependency has but your app lacks. matchingFallbacks instead handles build types/flavors the dependency is missing.
Two product flavors in different dimensions both set the same buildConfigField, and flavorDimensions = listOf("tier", "env"). Whose value wins?
- The flavor in 'env', since later-listed dimensions override earlier ones
- It raises a build error that you must resolve by hand manually
- The flavor in 'tier', since earlier-listed dimensions take priority
- Whichever flavor's name happens to sort last alphabetically
Answer: The flavor in 'tier', since earlier-listed dimensions take priority
Dimension declaration order sets override priority, highest first, so a flavor from the earlier-listed 'tier' dimension overrides one from the later 'env' dimension.
Which mechanism lets you move to a brand-new app signing key while older devices still trust updates as the same app?
- Requesting an upload key reset from within the Play Console
- Switching the build type's signingConfig at app install time
- Adding an applicationIdSuffix onto the release build type
- APK Signature Scheme v3 certificate lineage for key rotation
Answer: APK Signature Scheme v3 certificate lineage for key rotation
APK Signature Scheme v3 (Android 9+) records a certificate lineage that proves continuity from the old key to the new one, enabling signing-key rotation. An upload key reset replaces only the upload key, not the app signing key.
A freshly created module's release build type has no signingConfig assigned. What happens when you run assembleRelease as-is?
- It is signed automatically with the debug keystore for release builds
- It builds an unsigned release APK that needs a signingConfig first
- The build stops right away with a missing-keystore configuration error
- It is signed by Google Play's app signing key during assembleRelease
Answer: It builds an unsigned release APK that needs a signingConfig first
Without a signingConfig the release build still succeeds but emits an unsigned APK (app-release-unsigned.apk); it cannot be installed or uploaded until you wire a release signingConfig. Only the debug build type auto-uses the debug keystore.