Blog Infos
Author
Published
Topics
, , , ,
Author
Published

Image generated using CoPilot + Perplexity

In Android development, small mistakes can cause big problems.

Recently, our APK size spiked by 121MB overnight.🤯

After digging in, we traced it to a misplaced dependency.

This article explains how we found the issue 🐞 and the fix we put in place to prevent it from happening again.

🚨 The Problem: APK Size Explosion
  • One of our developers accidentally added the :testutils module as an implementation dependency instead of testImplementation.
  • This mistake caused our release app bundle to include Robolectric’s test-onlyresources, inflating the size by 121MB.
🧱 The Blocker: Play Console Size Limit
  • We first noticed the issue when trying to upload our app bundle to the Google Play Console.
  • The upload was blocked due to the 200MB compressed download size limit. This was a hard stop — we couldn’t proceed with the release until the size was reduced. ✋
🔍 Diagnosing the Issue with Git and APK Analyzer
  • I first used Android Studio’s APK Analyzer and found hundreds of fonts unexpectedly included in our APK.
  • To identify when this happened, I ran git bisect to find the exact commit causing the size increase.
    After isolating the commit, I used APK Analyzer again and confirmed that Robolectric was bundling these fonts into the APK.

Screenshot — APK Analyzer

Why This Matters

  • implementation includes dependencies in both compile and runtime classpaths.
  • testImplementation restricts them to test sources only.
  • Robolectric is meant for unit testingnot production — its inclusion in the release APK was a serious issue 💯
✅ The Fix: Correcting the Dependency
  • The immediate fix was simple:

 

- implementation(project(":testutils"))
+ testImplementation(project(":testutils"))
  • This change ensured that Robolectric and its assets were excluded from the final APK.
🛡️ The Prevention: A Custom Gradle Plugin
  • I created a Gradle plugin to enforce the correct usage of the :testutils module so that this does not happen again.
  • The build will fail 🛑 if it is added as an implementation dependency.

 

class TestOnlyDependencyCheckPlugin : Plugin<Project> {

    override fun apply(target: Project) {

        target.afterEvaluate {

            target.configurations.findByName("implementation")?.dependencies?.forEach {

                if (it is ProjectDependency && it.dependencyProject.path == ":testutils") {

                    throw GradleException(

                        "Module ':testutils' must not be used as an implementation dependency in ${target.path}. " +

                        "Use testImplementation instead."

                    )

                }

            }

        }

    }

}

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

Integration
  • We integrate the plugin into our feature plugin setup to run across all modules. This prevents any misuse of :testutils from reaching production.
💡 Lessons Learned
  • Dependency hygiene matters. Even test modules can wreak havoc if misconfigured.
  • APK Analyzer is your friend. It helped us pinpoint the exact assets bloating our APK.
  • Automation saves time. A small plugin can prevent hours of debugging.
  • Git bisect + APK Analyzer = powerful combo. Use them to track down regressions quickly.
  • Respect Play Console limits. They’re not just guidelines — they can block your release.
References
Stay in touch

This article was previously published on proandroiddev.com.

Menu