Unterschied zwischen SurfaceView und View?

211

Wann ist es notwendig oder besser, a SurfaceViewanstelle von a zu verwenden View?

Viktor
quelle

Antworten:

210

Alle Ansichten werden auf demselben GUI-Thread gezeichnet, der auch für alle Benutzerinteraktionen verwendet wird.

Wenn Sie also die GUI schnell aktualisieren müssen oder wenn das Rendern zu lange dauert und die Benutzererfahrung beeinträchtigt, verwenden Sie SurfaceView.

Niko Gamulin
quelle
2
Überprüfen Sie die Antwort von pierr, die weitere Details enthält.
Helin Wang
4
Offizielle Detailantwort: developer.android.com/guide/topics/graphics/2d-graphics.html
Helin Wang
So einfach ist das nicht mehr. Überprüfen Sie die Antwort von Pierre. Es enthält einen Link zum detaillierten Architekturdokument ( source.android.com/devices/graphics/architecture.html ) und erklärt, warum die Hardwarebeschleunigung beim Canvas-Rendering benutzerdefinierte Ansichten zu einer besseren Wahl machen kann.
Fadden
1
Wann sollte FrameLayout zum Stapeln von Ansichten anstelle von SurfaceView verwendet werden?
Igor Ganapolsky
103

Ein paar Dinge, die ich bemerkt habe:

  • SurfaceViews enthalten einen netten Rendering-Mechanismus, mit dem Threads den Inhalt der Oberfläche ohne Verwendung eines Handlers aktualisieren können (gut für Animationen).
  • Oberflächenansichten können nicht transparent sein, sondern nur hinter anderen Elementen in der Ansichtshierarchie angezeigt werden.
  • Ich habe festgestellt, dass sie für Animationen viel schneller sind als das Rendern in einer Ansicht.

Weitere Informationen (und ein gutes Anwendungsbeispiel) finden Sie im LunarLander-Projekt im Abschnitt mit den Beispielen des SDK.

Ralphleon
quelle
36
Zu Ihrer Information ... Ein SurfaceView kann jetzt transparent sein: stackoverflow.com/questions/5391089/…
Steve
@Ralphleon: Was meinst du mit Oberflächenansichten können nicht transparent sein? Können andere Ansichten die Oberflächenansicht überlappen? Kann ich beispielsweise vorübergehend eine ListView in einer Oberflächenansicht anzeigen?
Ashwin
78

aktualisiert am 05.09.2014

OK. Wir haben jetzt ein offizielles Dokument. Es sprach alles, was ich erwähnt habe, besser.


Lesen Sie mehr detailliert hier .

Ja, der Hauptunterschied besteht darin, dass SurfaceView im Hintergrund-Thread aktualisiert werden kann. Es gibt jedoch noch mehr, die Sie interessieren könnten.

  • surfaceView hat einen Oberflächenpuffer zugewiesen, während alle Ansichten einen Oberflächenpuffer gemeinsam nutzen, der von ViewRoot zugewiesen wird. Mit anderen Worten, SurfaceView kostet mehr Ressourcen.

  • SurfaceView kann nicht hardwarebeschleunigt werden (ab JB4.2), während 95% der Vorgänge in der normalen Ansicht mit openGL ES HW-beschleunigt werden.

  • Es sollte mehr Arbeit geleistet werden, um Ihre angepasste Oberflächenansicht zu erstellen. Sie müssen das SurfaceCreated / Destroy-Ereignis abhören, einen Render-Thread erstellen und vor allem den Render-Thread und den Haupt-Thread synchronisieren. Um die Ansicht anzupassen, müssen Sie jedoch nur die onDrawMethode überschreiben .

  • Der Zeitpunkt für die Aktualisierung ist unterschiedlich. Der normale Mechanismus zur Aktualisierung der Ansicht wird vom Framework eingeschränkt oder gesteuert: Sie rufen view.invalidateden UI-Thread oder einen view.postInvalidanderen Thread auf, um dem Framework anzuzeigen, dass die Ansicht aktualisiert werden soll. Die Ansicht wird jedoch nicht sofort aktualisiert, sondern wartet, bis das nächste VSYNC-Ereignis eintrifft. Der einfache Ansatz, um VSYNC zu verstehen, besteht darin, es als Timer zu betrachten, der alle 16 ms für einen 60-fps-Bildschirm startet. In Android wird das gesamte normale Ansichtsupdate (und die Anzeige tatsächlich, aber ich werde heute nicht darüber sprechen) mit VSYNC synchronisiert, um eine bessere Glätte zu erzielen. Zurück zur Oberflächenansicht können Sie sie jederzeit nach Belieben rendern. Ich kann jedoch kaum sagen, ob dies von Vorteil ist, da die Anzeige, wie bereits erwähnt, auch mit VSYNC synchronisiert ist.
pierrotlefou
quelle
2
Aus Ihrer Antwort geht hervor, dass es besser ist, eine von View abgeleitete Klasse als SurfaceView zu verwenden. Oder verstehe ich etwas falsch? Dies würde den meisten Tutorials zur Entwicklung von 2D-Spielen widersprechen.
Sturm
2
Bei @Storm ist zu berücksichtigen, dass eine SurfaceView den UI-Thread nicht blockieren sollte, wenn eine Ansicht nur vom UI-Thread geändert werden kann. Bei den meisten Spielen wird SurfaceViews ein gutes Stück Rendering ausführen, wodurch der UI-Thread mit einer einfachen Ansicht blockiert wird. Dies ist nach meinem Verständnis der Hauptvorteil einer SurfaceView.
zgc7009
Was meinst du einen Thread machen erstellen . Müssen wir das jedes Mal manuell erstellen?
IgorGanapolsky
44

Der Hauptunterschied besteht darin, dass SurfaceViewHintergrundköpfe darauf zurückgreifen Viewskönnen, dies aber nicht können. SurfaceViewsVerwenden Sie jedoch mehr Ressourcen, damit Sie sie nicht verwenden möchten, es sei denn, Sie müssen.

jcoder
quelle
"Sie verbrauchen jedoch mehr Ressourcen, sodass Sie sie nur verwenden möchten, wenn Sie dies müssen." - Wer nutzt mehr Ressourcen? Ansichten oder SurfaceViews?
Dror
6
Oberflächenansicht verbrauchen mehr Ressourcen als Ansichten
Ritesh Gune
1
@RiteshGune wie viel?
Alex Sifuentes
Wann wir müssen ?
IgorGanapolsky
12

A SurfaceViewist eine benutzerdefinierte Ansicht in Android, mit der Sie darin zeichnen können.

Der Hauptunterschied zwischen a Viewund a SurfaceViewbesteht darin, dass in der eine Ansicht gezeichnet wird UI Thread, die für die gesamte Benutzerinteraktion verwendet wird.

Wenn Sie die Benutzeroberfläche schnell genug aktualisieren und eine gute Menge an Informationen darin rendern möchten, ist eine SurfaceView die bessere Wahl.

Es gibt jedoch einige technische Aspekte SurfaceView:

1. Sie sind nicht hardwarebeschleunigt.

2. Normale Ansichten werden gerendert, wenn Sie die Methoden invalidateoder aufrufen. postInvalidate()Dies bedeutet jedoch nicht, dass die Ansicht sofort aktualisiert wird (A VSYNCwird gesendet und das Betriebssystem entscheidet, wann sie aktualisiert wird. Die SurfaceViewkann sofort aktualisiert werden.

3. Eine SurfaceView hat eine zugewiesene surface buffer, so ist es teurer

Setu Kumar Basak
quelle
Warum ist es wichtig, die Hardware zu beschleunigen ?
IgorGanapolsky
8

Einer der Hauptunterschiede zwischen Oberflächenansicht und Ansicht besteht darin, dass zum Aktualisieren des Bildschirms für eine normale Ansicht die Methode "Ungültig machen" aus demselben Thread aufgerufen werden muss, in dem die Ansicht definiert ist. Aber selbst wenn wir ungültig nennen, erfolgt die Aktualisierung nicht sofort. Sie tritt erst nach dem nächsten Eintreffen des VSYNC-Signals auf. Das VSYNC-Signal ist ein vom Kernel erzeugtes Signal, das alle 16,6 ms auftritt, oder dies wird auch als 60 Bilder pro Sekunde bezeichnet. Wenn wir also mehr Kontrolle über die Aktualisierung des Bildschirms haben möchten (z. B. für sehr schnelllebige Animationen), sollten wir keine normale Ansichtsklasse verwenden.

Auf der anderen Seite können wir bei der Oberflächenansicht den Bildschirm so schnell aktualisieren, wie wir möchten, und dies über einen Hintergrund-Thread. Das Aktualisieren der Oberflächenansicht hängt also nicht wirklich von VSYNC ab, und dies ist sehr nützlich, wenn wir Hochgeschwindigkeitsanimationen erstellen möchten. Ich habe nur wenige Schulungsvideos und eine Beispielanwendung, die all diese Dinge gut erklären. Bitte schauen Sie sich die folgenden Trainingsvideos an.

https://youtu.be/kRqsoApOr9U

https://youtu.be/Ji84HJ85FIQ

https://youtu.be/U8igPoyrUf8

Somenath Mukhopadhyay
quelle
0

Warum SurfaceView und nicht die klassische View-Klasse verwenden ...

Ein Hauptgrund ist, dass SurfaceView den Bildschirm schnell rendern kann.

Mit einfachen Worten, ein SV ist besser in der Lage, das Timing zu verwalten und Animationen zu rendern.

Um besser zu verstehen, was eine SurfaceView ist, müssen wir sie mit der View-Klasse vergleichen.

Was ist der Unterschied ... überprüfen Sie diese einfache Erklärung im Video

https://m.youtube.com/watch?feature=youtu.be&v=eltlqsHSG30

Nun, mit der Ansicht haben wir ein großes Problem ... das Timing des Renderns von Animationen.

Normalerweise wird onDraw () vom Android-Laufzeitsystem aufgerufen.

Wenn das Android-Laufzeitsystem onDraw () aufruft, kann die Anwendung nicht steuern

das Timing der Anzeige, und dies ist wichtig für die Animation. Wir haben eine Zeitlücke

zwischen der Anwendung (unserem Spiel) und dem Android-Laufzeitsystem.

Der SV kann onDraw () von einem dedizierten Thread aufrufen.

Also: Die Anwendung steuert das Timing. So können wir das nächste Bitmap-Bild der Animation anzeigen.

Takis Doris
quelle