Grundlegendes zu Canvas- und Oberflächenkonzepten

114

Ich habe Probleme, den Prozess des Zeichnens SurfaceViewund damit das gesamte Surface// Canvas/ BitmapSystem zu verstehen , das in Android verwendet wird.

Ich habe alle Artikel und API-Dokumentationsseiten gelesen, die ich auf der Website von Android-Entwicklern finden konnte, einige Tutorials zu Android-Grafiken, LunarLander-Quellcode und diese Frage .

Bitte sagen Sie mir, welche dieser Aussagen wahr sind, welche nicht und warum.

  1. Canvashat seine eigene daran Bitmapgebunden. Surfacehat seine eigene daran Canvasgebunden.
  2. Alle ViewFenster teilen sich das gleiche Surfaceund somit das gleiche Canvas.
  3. SurfaceViewist eine Unterklasse von View, die im Gegensatz zu Viewden Unterklassen anderer und sich Viewselbst ihre eigene Surfacezu zeichnen hat.

Es gibt noch eine zusätzliche Frage:

  • Warum wird eine SurfaceKlasse benötigt, wenn es bereits eine Canvasfür Operationen auf hoher Ebene mit Bitmap gibt? Geben Sie ein Beispiel für eine Situation, in der Canvases nicht für Arbeiten geeignet ist, die ausgeführt werden Surfacekönnen.
fyodorananiev
quelle

Antworten:

223

Hier sind einige Definitionen:

  • Eine Oberfläche ist ein Objekt, das Pixel enthält, die auf dem Bildschirm zusammengesetzt werden. Jedes Fenster, das Sie auf dem Bildschirm sehen (ein Dialogfeld, Ihre Vollbildaktivität, die Statusleiste), hat eine eigene Oberfläche, in die es gezeichnet wird, und Surface Flinger rendert diese in der richtigen Z-Reihenfolge zur endgültigen Anzeige. Eine Oberfläche verfügt normalerweise über mehr als einen Puffer (normalerweise zwei), um doppelt gepuffert zu rendern: Die Anwendung kann ihren nächsten UI-Status zeichnen, während der Oberflächen-Flinger den Bildschirm mit dem letzten Puffer zusammensetzt, ohne auf den Abschluss der Anwendung warten zu müssen Zeichnung.

  • Ein Fenster ist im Grunde so, als würden Sie an ein Fenster auf dem Desktop denken. Es hat eine einzelne Oberfläche, in der der Inhalt des Fensters gerendert wird. Eine Anwendung interagiert mit dem Fenstermanager, um Fenster zu erstellen. Der Fenstermanager erstellt für jedes Fenster eine Oberfläche und gibt sie der Anwendung zum Zeichnen. Die Anwendung kann in der Oberfläche zeichnen, was sie will. Für den Fenstermanager ist es nur ein undurchsichtiges Rechteck.

  • Eine Ansicht ist ein interaktives UI-Element innerhalb eines Fensters. An ein Fenster ist eine einzelne Ansichtshierarchie angehängt, die das gesamte Verhalten des Fensters bereitstellt. Wann immer das Fenster neu gezeichnet werden muss (z. B. weil sich eine Ansicht selbst ungültig gemacht hat), erfolgt dies in der Fensteroberfläche. Die Oberfläche ist gesperrt, wodurch eine Leinwand zurückgegeben wird, auf der gezeichnet werden kann. Eine Zeichnungsdurchquerung wird entlang der Hierarchie durchgeführt, wobei die Leinwand für jede Ansicht übergeben wird, um ihren Teil der Benutzeroberfläche zu zeichnen. Sobald dies erledigt ist, wird die Oberfläche entsperrt und veröffentlicht, sodass der gerade gezeichnete Puffer in den Vordergrund verschoben wird, um dann von Surface Flinger auf dem Bildschirm zusammengesetzt zu werden.

  • Eine SurfaceView ist eine spezielle Implementierung von View, die auch eine eigene dedizierte Oberfläche erstellt, in die die Anwendung direkt zeichnen kann (außerhalb der normalen Ansichtshierarchie, die andernfalls die einzelne Oberfläche für das Fenster gemeinsam nutzen muss). Die Funktionsweise ist einfacher als erwartet. SurfaceView fordert den Fenstermanager lediglich auf, ein neues Fenster zu erstellen, das Fenster entweder direkt hinter oder vor dem SurfaceView-Fenster in Z-Reihenfolge anzuordnen und entsprechend zu positionieren wo die SurfaceView im enthaltenden Fenster erscheint. Wenn die Oberfläche hinter dem Hauptfenster platziert wird (in Z-Reihenfolge), füllt SurfaceView auch seinen Teil des Hauptfensters mit Transparenz, damit die Oberfläche sichtbar ist.

  • Eine Bitmap ist nur eine Schnittstelle zu einigen Pixeldaten. Die Pixel werden möglicherweise von Bitmap selbst zugewiesen, wenn Sie direkt eines erstellen, oder es zeigt auf Pixel, die es nicht besitzt, z. B. was intern passiert, wenn ein Canvas zum Zeichnen an eine Oberfläche angeschlossen wird. (Eine Bitmap wird erstellt und zeigt auf den aktuellen Zeichenpuffer der Oberfläche.)

Beachten Sie auch, dass ein SurfaceView, wie dies impliziert, ein ziemlich schweres Objekt ist. Wenn Sie mehrere SurfaceViews in einer bestimmten Benutzeroberfläche haben, halten Sie inne und überlegen Sie, ob dies wirklich erforderlich ist. Wenn Sie mehr als zwei haben, haben Sie mit ziemlicher Sicherheit zu viele.

Hackbod
quelle
Vielen Dank! Die Antwort machte die Dinge klarer. Ein Teil über das Anschließen von Canvas an Surface ist jedoch unklar. Ich kann mir nicht vorstellen, wo eine solche Operation benötigt wird. Kann als nächstes ein Beispiel für diese Operation sein: Zeichnen einer Bitmap auf einem Canvas, das von SurfaceHolder mit der lockCanvas () -Methode erfasst wurde?
Fyodorananiev
1
So geschieht das Zeichnen Canvas ist die API für 2D-Zeichnungen. Wenn Sie o auf eine Oberfläche zeichnen möchten, müssen Sie einen Canvas erstellen, der auf seinen Puffer zeigt, damit Sie mit der Canvas 2d-Zeichen-API darauf zeichnen können.
Hackbod
6
Zusätzlich zur #hackbod'sAntwort SurfaceViewkann auch aus einem sekundären Thread gerendert werden, der für ViewObjekte nicht möglich ist
Mohanraj Balasubramaniam
47

Eine konzeptionelle Übersicht über Fenster, Oberfläche, Leinwand und Bitmap

Hier finden Sie eine sehr einfache und einfache konzeptionelle Übersicht darüber, wie die Interaktion zwischen Fenster, Oberfläche, Leinwand und Bitmap abläuft.
Manchmal hilft eine visuelle Darstellung sehr beim Verständnis verdrehter Konzepte.
Ich hoffe diese Grafik konnte jemandem helfen.

Sabeeh
quelle
4
Visualy Bilder sind besser als Text: D
Maveň
18

Eine Bitmap ist einfach ein Wrapper für eine Sammlung von Pixeln. Stellen Sie sich das als eine Reihe von Pixeln mit einigen anderen praktischen Funktionen vor.

Der Canvas ist einfach die Klasse, die alle Zeichenmethoden enthält. Es ähnelt der Grafikklasse in AWT / Swing, wenn Sie damit vertraut sind. Die gesamte Logik zum Zeichnen eines Kreises, einer Box usw. ist in Canvas enthalten. Eine Leinwand zeichnet auf eine Bitmap oder einen offenen GL-Container, aber es gibt keinen Grund, warum sie in Zukunft erweitert werden könnte, um auf andere Arten von Rastern zu zeichnen.

SurfaceView ist eine Ansicht, die eine Oberfläche enthält. Eine Oberfläche ähnelt einer Bitmap (sie hat einen Pixelspeicher). Ich weiß nicht, wie es implementiert ist, aber ich würde mir vorstellen, dass es sich um eine Art Bitmap-Wrapper mit zusätzlichen Methoden für Dinge handelt, die in direktem Zusammenhang mit Bildschirmanzeigen stehen (das ist der Grund für eine Oberfläche, eine Bitmap ist zu allgemein). Sie können eine Leinwand von Ihrer Oberfläche erhalten, die wirklich die Leinwand erhält, die der zugrunde liegenden Bitmap zugeordnet ist.

Deine Fragen.

1.Canvas hat eine eigene Bitmap angehängt. An der Oberfläche ist eine eigene Leinwand angebracht.

Ja, eine Zeichenfläche wird mit einer Bitmap (oder einem offenen GL-Bedienfeld) bearbeitet. Mit Surface erhalten Sie eine Leinwand, die auf jeder Oberfläche ausgeführt wird, die für den Pixelspeicher im Bitmap-Stil verwendet wird.

2. Alle Ansichten des Fensters haben dieselbe Oberfläche und somit dieselbe Leinwand.

Nein. Sie können so viele Oberflächenansichten haben, wie Sie möchten.

3.SurfaceView ist eine Unterklasse von View, die im Gegensatz zu anderen Unterklassen von View und View selbst eine eigene Oberfläche zum Zeichnen hat.

Ja. Genau wie ListView ist es eine Unterklasse von View, die eine eigene Listendatenstruktur hat. Jede Unterklasse von View macht etwas anderes.

sksamuel
quelle
1
Also, Bitmapund Surfacesind nur verschiedene Arten von Pixelspeicher und Canvaskönnen beide umschließen?
Fyodorananiev
2
Grundsätzlich ja. Außer dass Canvas nicht auf eine Oberfläche schreiben kann, arbeitet es mit dem, was Surface als eigenen Pixelspeicher verwendet (ohne auf die Android-Quelle zu schauen, kann ich nicht sicher sagen, was es ist). Es ist wahrscheinlich eine Art Bitmap-Erweiterung, da Canvas nur Konstruktoren für Bitmap und GL bereitstellt.
sksamuel
Tolle Hilfe, danke! Über Antwort 2. In meiner Frage habe ich Standardansichten gemeint, nicht SurfaceViews. Angenommen, ich habe RelativeLayout mit vielen Feldern und Schaltflächen. Wird in diesem Fall die Oberfläche an das gesamte Fenster angehängt und von allen Ansichten in der Ansichtshierarchie gemeinsam genutzt?
Fyodorananiev
1
Denken Sie daran, Oberfläche ist nur eine Sammlung von Pixeln. So hat jede Oberflächenansicht ihre eigene Oberfläche und jede kann auf einem anderen Teil des Bildschirms gerendert werden. Sie müssen den Bildschirm nicht ausfüllen (obwohl dies die übliche Verwendung ist, um Grafiken in einem Vollbildspiel zu rendern).
sksamuel
1
Ich würde Bitmap und Surface wirklich nicht als gleichwertig betrachten. Eine Oberfläche ist ein Objekt, das Surface Flinger, der Fensterkomponitor, kennt. Das heißt, es ist etwas direkt auf dem Bildschirm sichtbar, hat eine Z-Reihenfolge auf dem Bildschirm usw.
Hackbod