-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.