Was ist der Unterschied zwischen -anydpi und -nodpi?

108

Wenn Sie den Vector Asset-Assistenten in Android Studio 1.5.0 verwenden, wird jedes mit diesem Assistenten importierte Vektor-Zeichen-XML verwendet res/drawable/.

Das build/Verzeichnis und die resultierende APK zeigen jedoch, dass diese XML-Dateien in ein res/drawable-anydpi-v21/Ressourcenverzeichnis verschoben werden . Der -v21Teil ist sinnvoll, da er VectorDrawablenur auf API Level 21+ unterstützt wird. Allerdings -anydpischeint nicht dokumentiert zu werden. Ich hätte erwartet -nodpi, sowohl für das ursprüngliche Importziel als auch dafür, wohin das Build-System es verschieben möchte .

Hat jemand offizielle Aussagen darüber gesehen, was -anydpibedeutet und in welcher Beziehung es steht -nodpi? Ich suche nach praktischen Effekten, nicht nur nach dem, was einige Codekommentare andeuten.

CommonsWare
quelle

Antworten:

106

nodpi

Dies sind dichteunabhängige Ressourcen. Das System skaliert keine mit diesem Qualifikationsmerkmal gekennzeichneten Ressourcen, unabhängig von der aktuellen Bildschirmdichte.

Zum Beispiel:

  • drawable- nodpi /dot.png

Der Punkt erscheint auf xxhdpi klein, auf ldpi groß.

Der Ressourcenauflöser entspricht jedoch einem bestimmten Qualifikationsmerkmal, falls vorhanden.

Zum Beispiel

  • drawable- hdpi /eg.png
  • drawable- nodpi -v21 / eg.xml

Auf einem HDPI-Gerät von Lollipop (API 21) wird die Bitmap verwendet.

Auf einem Lollipop (API 21) xhdpi-Gerät wird der Vektor verwendet.

anydpi

Diese Ressourcen haben in jeder dpi Vorrang.

Zum Beispiel

  • drawable- hdpi /eg.png
  • drawable- anydpi -v21 / eg.xml

Auf einem Lollipop (API 21) -Hdpi-Gerät wird der Vektor verwendet.

Auf einem Lollipop (API 21) xhdpi-Gerät wird der Vektor verwendet.

Referenz

Hinweis : anydpi wurde in Änderung Ic3288d0236fe0bff20bb1599aba2582c25b0db32 hinzugefügt .

rds
quelle
Das sehe ich nicht. Ich zitiere mein Kopfgeld: "Bei zwei Editionen derselben Ressource in res / drawable-nodpi / und res-drawable-mdpi / erhalte ich die res / drawable-nodpi / Edition auf einem Nexus 5 mit Android 6.0, das ein -xxhdpi ist Gerät". Haben Sie ein Beispielprojekt, das das von Ihnen zitierte Verhalten demonstriert?
CommonsWare
Das liegt daran, dass du es benutzt hast drawable. Das Verhalten des SDK kann sich geändert haben. Siehe VectorDrawable: Android lädt xhdpi PNGs anstelle der Vektorressource
rds
"Das liegt daran, dass Sie Drawable verwendet haben" - das haben Sie auch in Ihrer Antwort getan. Jedes einzelne Ressourcenverzeichnis, das Sie in Ihrer Antwort zitieren, ist ein drawableRessourcenverzeichnis, genau wie beide Verzeichnisse, die ich in meinem Kopfgeld zitiert habedrawable Ressourcenverzeichnisse sind.
CommonsWare
"Auf einem xxxdpi nimmt das Framework die hdpi-Bitmap auf." - das ist genau das, was nicht passiert, obwohl meine Tests auf einem sind-xxhdpi Gerät durchgeführt werden. Ich habe res/drawable-mdpi/nodpi_and_m.pngund res/drawable-nodpi/nodpi_and_m.xml. Auf einem Nexus 5- -xxhdpiGerät wird die Ressource verwendet res/drawable-nodpi/nodpi_and_m.xml. Entsprechend Ihrem Algorithmus und meinen Erwartungen res/drawable-mdpi/nodpi_and_m.pngsollte verwendet werden. Das ist nicht was passiert.
CommonsWare
2
Fazit: Sie sollten Vektoren in platzieren drawable-anydpi-v21. Wenn Sie über die Support-Vector-Drawable-Bibliothek verfügen, können Sie diese in drawable-anydpioder einfach platzieren drawable.
rds
17

Der Quellcode enthält die folgenden Kommentare (Zeile 639):

/**
 * Value for {@link #densityDpi} for resources that scale to any density (vector drawables).
 * {@hide}
 */
public static final int DENSITY_DPI_ANY = 0xfffe;

/**
 * Value for {@link #densityDpi} for resources that are not meant to be scaled.
 * {@hide}
 */
public static final int DENSITY_DPI_NONE = 0xffff;

Hoffe, das beseitigt die Verwirrung.

Vishavjeet Singh
quelle
8
"Hoffe das klärt die Verwirrung" - nicht wirklich. Es ist unklar, was der Unterschied zwischen "Skalierung auf eine beliebige Dichte" und "nicht skalierbar" in der Praxis bedeutet. Drawables in -nodpiVerzeichnissen werden mit Sicherheit basierend auf der Größe skaliert, je nachdem, welche Regeln für die Verwendung des Drawables gelten.
CommonsWare
"Nicht für die Skalierung gedacht" bedeutet, dass sie nicht skaliert werden, unabhängig davon, was der Programmierer tut oder welche Dichte er hat.
Vishavjeet Singh
Ich denke, sie meinen mit dem Ausdruck "auf jede Dichte skalieren", dass sie sich auf Vektorzeichnungen beziehen, die skaliert werden, um jeder Dichte zu entsprechen, egal wie groß die Dichte ist.
Vishavjeet Singh
3
Es wurde in android.googlesource.com/platform/frameworks/base/+/31245b4%5E hinzugefügt ! , und daraus können Sie lernen, es hat wahrscheinlich einen Fehler behoben 17007265
marcinj
1
@ MarcinJędrzejewski: Tatsächlich gibt mir der Kommentar "Als beste Übereinstimmung ausgewählt, es sei denn, es gibt eine Konfiguration, die genau der angeforderten Dichte entspricht" zu diesem Commit einen Hinweis. Vielen Dank!
CommonsWare
10

nodpi: Ressourcen für alle Dichten. Dies sind dichteunabhängige Ressourcen. Das System skaliert keine mit diesem Qualifikationsmerkmal gekennzeichneten Ressourcen, unabhängig von der aktuellen Bildschirmdichte.

anydpi: Dieses Qualifikationsmerkmal entspricht allen Bildschirmdichten und hat Vorrang vor anderen Qualifikationsmerkmalen. Dies ist nützlich für Vektorzeichnungen. In API Level 21 hinzugefügt.

dzikovskyy
quelle
9

Ich benutze Drawable-Nodpi für alles, einschließlich vieler großer Grafiken für mein Spiel. Eine undokumentierte Folge der Vergrößerung Ihrer Grafiken ist, dass die Speichernutzung exponentiell erhöht wird. Wenn Sie also eine 1-MB-Grafik zum Zeichnen haben, wird sie je nach Auflösung des Benutzergeräts auf 4 MB, 16 MB oder 64 MB skaliert. Und die Geräteauflösungen steigen weiter. Diese Vergrößerung erhöht natürlich nicht die Schärfe der Grafik. Die Zeichenaktionen können festlegen, wie groß jede Grafik im Verhältnis zur Bildschirmgröße sein soll, ohne dass die App mit mehreren Zeichenordnern aufgebläht werden muss.

Androidcoder
quelle
3
unterschätzte Antwort. Ich bin auf dasselbe Problem gestoßen: hatte ein 100 KB großes Image, hatte aber häufig OOM-Fehler beim Laden. Die App stürzte ab und gab an, dass 18 MB nicht zugewiesen werden konnten !!! Konnte nicht verstehen, wie diese 100 KB in 18 MB umgewandelt werden konnten, aber es war tatsächlich das Ergebnis dieser Skalierung. Das Umschalten des Bildes auf no-dpi löste das Problem.
Simon Ninon