Gradle & Code Quality

Gradle Task Dependencies: dependsOn Is Not mustRunAfter

dependsOn adds a task dependency; mustRunAfter only orders tasks that are already scheduled. Confusing them can produce a build that works when two tasks are invoked manually but fails when a consumer task runs alone.

By Updated 2 min read

Choose dependency or ordering deliberately

Relationship Effect
dependsOn(producer) Schedules the producer before the consumer
mustRunAfter(other) Orders both tasks when both are scheduled
shouldRunAfter(other) Expresses a weaker ordering preference
finalizedBy(cleanup) Schedules a finalizer under Gradle's documented rules

The task execution reference describes the differences. Ordering does not establish that a required output exists.

Prefer declared inputs and outputs

If one task consumes another task's output, model that relationship through task providers and declared properties where possible. This gives Gradle information for dependency inference, incremental execution and caching.

An illustrative explicit dependency is:

KOTLIN · REFERENCE EXAMPLE
val generateManifest = tasks.register("generateManifest") {
    // A real task should declare its inputs and output file.
}
tasks.register("packageExample") {
    dependsOn(generateManifest)
}

This example shows scheduling only. It is not a working Android packaging task and should not replace AGP's own artifact APIs.

Test the consumer alone

Run the consumer task from a clean relevant output state. If it succeeds only after a developer manually ran the producer, the dependency model is incomplete.

Also test parallel execution where your build supports it. Accidental ordering that works in a serial local build can fail in CI when tasks run concurrently.

Avoid global task-order patches

A broad mustRunAfter rule across all tasks can hide the symptom without declaring the missing data relationship. It may also slow the build and make future plugin upgrades fragile.

Use plugin-supported APIs for generated Android sources or resources rather than relying on internal task names that can change between AGP versions.

Review with build evidence

APKLint's Build Analyzer can help inspect suspicious task wiring, but it cannot execute the actual graph from a fragment. Retain the successful task invocation, declared inputs/outputs and configuration-cache results with the change. The goal is a correct dependency model, not merely a command that happened to finish once.

Sources and further reading

  1. Gradle: Controlling task execution

Reference review: 22 September 2026. Examples illustrate the workflow; check your installed versions, release artifact and account-specific Console requirements before applying them. This guide is not a claim that APKLint executed your project or verified your private account.

APKLint

Android inspection tools and practical release guides. About APKLint · Report a correction