-nodpi, -anydpi, and WTF?

Android Studio exposes developers to -nodpi and -anydpi in various places. For example, if you use the New Resource Directory wizard thing, and you choose to add a density qualifier to the directory, you will see “No Density” (-nodpi) and “Any Density” (-anydpi) options.

Some of you might expect these to be well-documented.

In a word, no.

However, courtesy of a fair amount of experimentation (largely done as part of work on this Stack Overflow question and this answer), their use becomes at least a bit clearer. Many thanks to Stack Overflow user rds for the help!

nodpi: Fallback

A drawable in res/drawable-nodpi/ is valid for any screen density. However, if there is another drawable with the same base name in a density-specific directory, and the device running your app happens to have that screen density, the density-specific resource will be used. As a result, -nodpi becomes a fallback, to be used in cases where you do not have something specific for a density.

For example, suppose that we have res/drawable-nodpi/foo.xml and res/drawable-xxhdpi/foo.png. An -xxhdpi device would use the PNG; all other devices would use the XML.

anydpi: Takeover

A drawable in res/drawable-anydpi/ also is valid for any screen density. However, in this case, the -anydpi variant trumps any density-specific variant.

For example, suppose that we have res/drawable-anydpi/foo.xml and res/drawable-xxhdpi/foo.png. All devices would use the XML, even -xxhdpi devices.

For this reason, often you will see -anydpi used in conjunction with other qualifiers. A popular one will be -v21, to restrict the resources to be used on API Level 21+ devices. It so happens that one particular type of XML-defined drawable — the vector drawable — was introduced in API Level 21.

For example, suppose that we have res/drawable-anydpi-v21/foo.xml and res/drawable-xxhdpi/foo.png. In this case, all Android 5.0+ devices would go with the XML. All -xxhdpi devices running Android 4.4 or older would go with the PNG. And all other devices running Android 4.4 or older would also go with that same PNG, albeit with some rescaling to adjust the effective density.

In particular, vector drawables cannot go in a -nodpi directory if your minSdkVersion is below 21. While Android Studio generates PNGs from your vector drawables for use on older devices, it seems to skip those in -nodpi directories, for unclear reasons.

No Qualifier: Just Say “WTF?”

res/drawable/ is a synonym for res/drawable-mdpi/, for backwards compatibility with really old Android apps, written before we had density-specific resources. Hence, IMHO, res/drawable/ is not really an appropriate choice for density-independent drawables.