Code Shrinking with R8
AndroidDEX bytecode not optimized by R8. Enabling code shrinking, tree shaking, and obfuscation typically reduces app size by 10-65%.
R8 is Android's default code optimizer and shrinker, integrated into the Android Gradle Plugin. It operates directly on DEX bytecode in a single compilation step, performing four core optimizations: tree shaking (removing unreachable code), code optimization (inlining methods, merging classes, removing dead branches), obfuscation (shortening class/field/method names to reduce string table size), and desugaring. R8 full mode (default since AGP 8.0) applies more aggressive optimizations: default constructors are not implicitly kept, access modification is enabled by default, and annotations are only preserved for items matched by explicit keep rules.
Why this happens
Third-party library bloat: Libraries like Google Play Services, Jetpack, or Gson include thousands of classes, but apps typically use only a fraction of them. Without R8, all library code ships in the APK.
Unused code paths from feature flags, dead code from previous iterations, and debug-only utilities inflate the DEX file.
Verbose class/method names (e.g., com.example.myapp.feature.analytics.AnalyticsEventTracker) consume significant space in the DEX string table.
Auto-generated code from annotation processors, data binding, and protocol buffer generators creates substantial boilerplate that may be partially unused.
Multi-DEX overhead: Without shrinking, apps easily exceed the 64K method limit, requiring multiple DEX files with duplicated metadata.
Size impact
R8 is often the single highest-impact optimization for Android apps. Full mode delivers even greater savings due to aggressive class merging and inlining.
Reddit (R8 full mode)
14% reduction in app size
LinkedIn (R8 + AGP 4.1)
10.5 MB total decrease
Google IOSched sample
65% DEX size reduction
R8 vs ProGuard
~10% compaction vs 8.5%
How we detect it
Uses APK Analyzer to inspect the classes.dex file size and method count. Checks whether R8 outputs (mapping.txt, usage.txt) indicate code was removed. Compares referenced vs. defined methods to gauge shrinking effectiveness.
How to fix
1
Enable R8 in release builds
Set isMinifyEnabled and isShrinkResources to true in your release build type. Use the default proguard-android-optimize.txt rules file.
build.gradle.kts (app module)
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}2
Ensure R8 full mode is active
R8 full mode is default since AGP 8.0. Verify it is not explicitly disabled in gradle.properties.
3
Add keep rules for reflection-dependent code
R8 cannot detect code accessed via reflection, Class.forName(), or JNI. Add explicit keep rules for data models used with Gson/Moshi, JNI-called methods, and @Keep-annotated classes.
proguard-rules.pro
# Keep classes used via reflection (e.g., Gson data models)
-keepclassmembers class com.example.myapp.model.** {
<fields>;
}
# Keep JNI-called methods
-keepclasseswithmembers class * {
native <methods>;
}
# Aggressive optimization
-repackageclasses
-allowaccessmodification4
Enable optimized resource shrinking (AGP 8.12.0+)
Combines code and resource analysis in a single R8 pass for better removal of unused resources.
gradle.properties
android.r8.optimizedResourceShrinking=trueImportant: Reflection crashes are the #1 pitfall. Missing keep rules cause ClassNotFoundException or NoSuchMethodException at runtime. Always test release builds on physical devices. R8 full mode does not implicitly keep default constructors, so code using getDeclaredConstructor().newInstance() will fail without explicit keep rules.
Powered by Bitrise, trusted by 8,500+ brands
Size Analyzer is built by Bitrise, the leading mobile DevOps platform used by over 400,000 developers at companies like Shopify, TripAdvisor, and BuzzFeed. Free forever. No signup required.
Bitrise provides a full-stack mobile DevOps solution that unites the tools, processes, and testing frameworks engineering teams need to ship best-in-class mobile experiences.