R8, Shrinking & App Size Flashcards

BUILD & TOOLING › Gradle

Which two Gradle flags enable R8's code and resource shrinking, and how do they relate?
minifyEnabled=true turns on R8 (code shrinking, obfuscation, optimization); shrinkResources=true removes unused resources but only works when minifyEnabled is also true.
Name the distinct things R8 does to your bytecode.
Code shrinking (tree-shaking unreachable code from manifest entry points), obfuscation (renaming classes/methods/fields to short names), and optimization (inlining, class merging, dead-branch removal). Resource shrinking runs alongside it.
Why does reflection break under R8, and which serialization library most often needs manual keep rules?
R8 can't see reflective access, so it may strip or rename those members. Hilt, Moshi codegen, and kotlinx.serialization ship their own consumer rules; Gson typically needs manual -keep on the model classes.
What is mapping.txt and how do you use it?
It maps original names to R8's obfuscated names for one build. Upload it to the Play Console (or run the retrace tool) to turn an obfuscated release stack trace back into readable symbols.
Difference between -keep and -keepclassmembers?
-keep protects the class and its members from both removal and renaming. -keepclassmembers protects only the listed members; R8 can still remove the whole class if nothing references it.
What does uploading an Android App Bundle let Google Play do that a universal APK can't?
Play generates optimized split APKs per device, splitting by screen density, ABI/architecture, and language, so each user downloads only the code and resources their device needs.
How do dynamic feature modules reduce initial app size?
Play Feature Delivery serves them on-demand, conditionally, or at install-time, so the base download excludes optional features until the user actually needs them.
Why must resources.arsc not be compressed, and what's the native-library equivalent?
The platform/ART seeks and memory-maps directly into resources.arsc, so compressing it breaks that and hurts performance. Similarly, set useLegacyPackaging=false to ship .so files uncompressed and avoid on-install extraction.
Why prefer @IntDef over a Kotlin/Java enum for size-sensitive code?
Each enum adds roughly 1.0-1.4 KB to classes.dex. @IntDef gives compile-time type safety but compiles down to plain integers, which R8 keeps small.

Back to R8, Shrinking & App Size