Skip to content
tezvyn:

Roles of minifyEnabled and shrinkResources and common pitfalls

Source: developer.android.comMediumHow cards are made

Roles of minifyEnabled and shrinkResources and common pitfalls

Tests R8 code shrinking vs resource stripping and runtime risks. Outline: minifyEnabled shrinks code; shrinkResources removes unused assets and requires minifyEnabled; dynamic access like getIdentifier() crashes; keep resources with tools:keep or keep.xml.

What's really being asked

Whether you understand the two distinct stages of Android release build optimization and their dependency chain. Interviewers want to see that you know minifyEnabled is about code and shrinkResources is about assets, and that you have been burned by or at least understand the runtime risks of dynamic resource access.

A GOOD ANSWER COVERS four things in order. First, define minifyEnabled as the Gradle flag that enables R8 to perform code shrinking, optimization, and name obfuscation. It analyzes bytecode to remove unused classes, methods, and fields. Second, define shrinkResources as the flag that strips unused resources from the packaged APK or AAB. Third, state the critical dependency: shrinkResources only works when minifyEnabled is true because the resource shrinker relies on the code shrinkers reachability graph to know which resources are referenced from code. Fourth, describe the common pitfall and mitigation. The pitfall is that resources accessed dynamically via methods like getIdentifier, reflection, or certain data binding patterns are invisible to static analysis, so the shrinker removes them and the app crashes with ResourceNotFoundException at runtime. The mitigation is to explicitly keep those resources using the tools:keep attribute directly in resource XML files or by creating a res/raw/keep.xml file with keep directives. Refactoring away from dynamic resource lookup is the cleanest long term fix.

COMMON WRONG ANSWERS include treating the two flags as if they do the same thing, saying shrinkResources removes code, or claiming shrinkResources works independently without minifyEnabled. Another red flag is suggesting you should simply disable shrinkResources in production to avoid bugs rather than using keep rules. Saying you have never used shrinkResources because it is too risky also signals a lack of production build ownership.

What usually comes next

How would you debug which resources were removed? The interviewer might ask about the res/raw/keep.xml syntax or how to use the tools:shrinkMode attribute set to strict versus safe. They may also ask how app bundles affect this, or how library modules handle resource shrinking. Another angle is asking how you would measure APK size impact before and after enabling these flags.

A concrete example

Suppose your app has a feature module that inflates layouts dynamically based on server responses using getIdentifier("layout_" + serverType, "layout", packageName). With shrinkResources true, R8 sees no direct references to R.layout.layout_premium or R.layout.layout_basic in compiled code, so the resource shrinker strips them. When the server returns premium, the app crashes. To fix it, you add tools:keep="@layout/layout_premium,@layout/layout_basic" to a keep.xml in res/raw, or you add tools:keep on the root tag of those layout files if they are referenced indirectly. This tells the shrinker to retain them despite the lack of static references.

Interview question

Which statement correctly explains why shrinkResources depends on minifyEnabled?

  • a.shrinkResources strips unused Java source files before R8 compiles them
  • b.Both flags are aliases for the same R8 optimization pass and cannot run separately
  • c.minifyEnabled must run first to rename resource IDs so shrinkResources can match them
  • d.shrinkResources needs the code reachability graph from R8 to know which resources are referenced in compiled codeCorrect
Why?

shrinkResources requires minifyEnabled because it uses R8's reachability graph to determine which assets are referenced from code. The distractor that the flags are aliases is tempting but wrong, since they optimize distinct stages—code versus resources.

Just read this? Test yourself on what you have been reading.

Read the original → developer.android.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on android — each one lists the topics its interview covers.

See open roles