Establish a release baseline
Build the variant you ship with its intended signing and optimization settings. Record the source revision, dependency lock state, artifact type and native architectures. Analyze DEX, resources, assets and native libraries separately; an optimization aimed at Java bytecode will not meaningfully reduce a package dominated by video files.
./gradlew :app:assembleRelease
apkanalyzer apk file-size app/build/outputs/apk/release/app-release.apk
apkanalyzer files list app/build/outputs/apk/release/app-release.apk
Output paths vary by flavors and module names. Use the actual output produced by your build, not a stale file from an earlier run.
Pick the highest-value change
| Dominant contributor | Investigate first |
|---|---|
| DEX code | Unused dependencies, R8 optimization and overly broad keep rules |
| Raster images | Excess resolution, duplicate formats and unnecessary variants |
| Native libraries | Required ABIs, duplicated SDK runtimes and unused plugins |
| Assets | Test data, bundled originals and content suitable for asset delivery |
| Resources | Unused resources and configuration choices appropriate to the audience |
Do not remove language or density support merely because it is visible in a chart. Decide what the product supports, then measure the effect on real delivery. Android size guidance.
Enable optimization deliberately
In a Kotlin DSL Android application module, the basic release settings are:
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
This fragment is not a complete build file. Add narrowly scoped rules only when reflection, serialization or native entry points require them. Blanket rules keeping entire dependency trees can eliminate much of the benefit. R8 configuration.
Measure one intervention at a time
Rebuild after each meaningful change and compare identical artifact types. Keep a short note such as “removed unused image editor dependency; native library category decreased; image import smoke test passed in our environment.” Do not invent a percentage before measuring it.
For native apps, consider device-targeted delivery before deleting an ABI. The ABI documentation explains architecture packaging; supporting fewer devices is a product decision, not a free optimization.
Test the failure-prone release paths
Run login, purchase restoration, deep links, serialization, background work and any dynamically loaded features relevant to the app. These can behave differently after shrinking. Preserve the matching mapping file for crash diagnosis.
Use APKLint's Size Analyzer to identify large packaged entries and its Size Optimization Guide to organize changes. APKLint does not rewrite your APK into a smaller, re-signed production build; the final fix belongs in the source and build pipeline.
Sources and further reading
- Android Developers: Reduce your app size
- Android Developers: Enable optimization with R8
- Android NDK: Android ABIs
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.



