Grafiken

Symbol für die Android Graphics HAL

Das Android-Framework bietet eine Vielzahl von APIs für das Rendern von 2D- und 3D-Grafiken, die mit den Implementierungen von Grafiktreibern der Hersteller interagieren. Daher ist es wichtig, dass Sie die Funktionsweise dieser APIs auf einer höheren Ebene gut verstehen. Auf dieser Seite wird die Graphics Hardware Abstraction Layer (HAL) vorgestellt, auf der diese Treiber basieren. Bevor Sie mit diesem Abschnitt fortfahren, sollten Sie sich mit den folgenden Begriffen vertraut machen:

Canvas (allgemeiner Begriff), Canvas (API-Element)
Ein Canvas ist eine Zeichenfläche, auf der die Komposition der tatsächlichen Bits mit einer Bitmap oder einem Surface-Objekt erfolgt. Die Klasse Canvas enthält Methoden zum Zeichnen von Bitmaps, Linien, Kreisen, Rechtecken, Text usw. und ist an eine Bitmap oder Oberfläche gebunden. Ein Canvas ist die einfachste Möglichkeit, 2D-Objekte auf dem Bildschirm zu zeichnen. Die Basisklasse ist Canvas.
Drawable
Ein „Drawable“ ist eine kompilierte visuelle Ressource, die als Hintergrund, Titel oder anderer Teil des Bildschirms verwendet werden kann. Ein Drawable wird in der Regel in ein anderes UI-Element geladen, z. B. als Hintergrundbild. Ein Drawable kann keine Ereignisse empfangen, weist aber verschiedene andere Eigenschaften wie Status und Planung zu, um Unterklassen wie Animationsobjekte oder Bildbibliotheken zu ermöglichen. Viele Drawable-Objekte werden aus Drawable-Ressourcendateien geladen – XML- oder Bitmap-Dateien, die das Bild beschreiben. Zeichnungsressourcen werden in Unterklassen von android.graphics.drawable kompiliert. Weitere Informationen zu Drawables und anderen Ressourcen finden Sie unter App-Ressourcen – Übersicht.
Layoutressource
Eine Layoutressource ist eine XML-Datei, die das Layout eines Aktivitätsbildschirms beschreibt. Weitere Informationen finden Sie unter Layout-Ressource.
Nine-Patch (9-Patch, NinePatch)
Ein Nine-Patch ist eine Bitmap-Ressource, die in der Größe angepasst werden kann und für Hintergründe oder andere Bilder auf dem Gerät verwendet werden kann. Weitere Informationen finden Sie unter Nine-Patch.
OpenGL ES
OpenGL ES ist eine plattformübergreifende API zum Rendern von 2D- und 3D-Grafiken. Android bietet OpenGL ES-Bibliotheken für hardwarebeschleunigtes 3D-Rendering. Für das 2D-Rendering ist ein Canvas die einfachere Option. OpenGL ES ist im Android Native Development Kit (NDK) verfügbar. Die Pakete android.opengl und javax.microedition.khronos.opengles machen OpenGL ES-Funktionen verfügbar.
Oberfläche (allgemeiner Begriff), Surface (API-Element)
Eine Oberfläche stellt einen Speicherblock dar, der auf dem Bildschirm zusammengesetzt wird. Eine Oberfläche enthält einen Zeichenbereich und bietet verschiedene Hilfsmethoden zum Zeichnen von Layern und zum Anpassen der Größe des Surface-Objekts. Verwenden Sie die Klasse SurfaceView anstelle der Klasse Surface.
Oberflächenansicht (allgemeiner Begriff), SurfaceView (API-Element)
Eine Oberflächenansicht ist ein View-Objekt, das ein Surface-Objekt zum Zeichnen umschließt und Methoden zum dynamischen Festlegen seiner Größe und seines Formats bereitstellt. Eine Surface-Ansicht bietet die Möglichkeit, unabhängig vom UI-Thread zu zeichnen, was für ressourcenintensive Vorgänge wie Spiele oder Kameravorschaubilder nützlich ist. Allerdings wird dadurch zusätzlicher Arbeitsspeicher benötigt. Eine Surface-Ansicht unterstützt sowohl Canvas- als auch OpenGL ES-Grafiken. Die Basisklasse für ein SurfaceView-Objekt ist SurfaceView.
Thema
Ein Design ist eine Gruppe von Eigenschaften wie Textgröße und Hintergrundfarbe, die zusammengefasst werden, um verschiedene Standardanzeigeeinstellungen zu definieren. Android bietet einige Standarddesigns, die in R.style aufgeführt sind und mit Theme_ beginnen.
Ansicht (allgemeiner Begriff), View (API-Element)
Eine View zeichnet einen rechteckigen Bereich auf dem Bildschirm und verarbeitet Klick-, Tastendruck- und andere Interaktionsereignisse. Die Klasse View ist die Basisklasse für die meisten Layoutkomponenten eines Aktivitäts- oder Dialogfeldbildschirms, z. B. Textfelder und Fenster. Ein View-Objekt empfängt Aufrufe von seinem übergeordneten Objekt (siehe ViewGroup), um sich selbst zu zeichnen, und informiert sein übergeordnetes Objekt über seine bevorzugte Größe und Position, die vom übergeordneten Objekt möglicherweise nicht berücksichtigt wird. Weitere Informationen finden Sie unter View.
Ansichtsgruppe (allgemeiner Begriff), ViewGroup (API-Element)
Eine View-Gruppe gruppiert eine Reihe von untergeordneten Ansichten. Die Ansichtsgruppe ist dafür verantwortlich, wo untergeordnete Ansichten positioniert werden und wie groß sie sein dürfen. Außerdem ruft sie die einzelnen Ansichten auf, damit sie sich bei Bedarf selbst zeichnen. Einige Ansichtsgruppen sind unsichtbar und dienen nur dem Layout, während andere eine integrierte Benutzeroberfläche haben, z. B. ein Scrollfeld. Ansichtsgruppen befinden sich im Paket android.widget, erweitern aber die Klasse ViewGroup.
Hierarchie ansehen
Eine Ansichtshierarchie ist eine Anordnung von Ansichts- und Ansichtsgruppenobjekten, die die Benutzeroberfläche für jede Komponente einer App definiert. Die Hierarchie besteht aus Ansichtsgruppen, die eine oder mehrere untergeordnete Ansichten oder Ansichtsgruppen enthalten. Mit dem Hierarchy Viewer, der im Android SDK enthalten ist, können Sie eine visuelle Darstellung einer Ansichtshierarchie zum Debuggen und Optimieren abrufen.
Vulkan
Vulkan ist eine plattformübergreifende API mit geringem Aufwand für leistungsstarke 3D-Grafiken.
Widget
Ein Widget ist eine von mehreren vollständig implementierten Ansichtsklassen, die Formularelemente und andere UI-Komponenten wie ein Textfeld oder ein Pop-up-Menü rendern. Da ein Widget vollständig implementiert ist, übernimmt es die Messung, das Zeichnen und die Reaktion auf Bildschirmereignisse selbst. Widgets befinden sich im Paket android.widget.
Fenster (allgemeiner Begriff), Window (API-Element)
In einer Android-App ist ein Fenster ein Objekt, das von der abstrakten Klasse Window abgeleitet wird. Diese Klasse gibt die Elemente eines generischen Fensters an, z. B. das Erscheinungsbild, den Text der Titelleiste sowie die Position und den Inhalt von Menüs. Für Dialogfelder und Aktivitäten wird eine Implementierung der Klasse Window verwendet, um ein Window-Objekt zu rendern. Sie müssen die Window-Klasse nicht implementieren oder Fenster in Ihrer App verwenden.

App-Entwickler können Bilder auf drei Arten auf dem Bildschirm darstellen: mit Canvas, OpenGL ES oder Vulkan.

Android-Grafikkomponenten

Unabhängig davon, welche Rendering-API Entwickler verwenden, wird alles auf einer Oberfläche gerendert. Die Oberfläche repräsentiert die Produzentenseite einer Pufferwarteschlange, die häufig von SurfaceFlinger genutzt wird. Jedes Fenster, das auf der Android-Plattform erstellt wird, wird durch eine Surface unterstützt. Alle gerenderten sichtbaren Oberflächen werden von SurfaceFlinger auf dem Display zusammengesetzt.

Das folgende Diagramm zeigt, wie die wichtigsten Komponenten zusammenarbeiten:

Komponenten für das Rendern von Bildern

Abbildung 1: So werden Oberflächen gerendert.

Die Hauptkomponenten werden in den folgenden Abschnitten beschrieben.

Produzenten von Bildstreams

Ein Bildstream-Producer kann alles sein, was Grafikpuffer für die Nutzung erzeugt. Beispiele hierfür sind OpenGL ES, Canvas 2D und Mediaserver-Videodecoder.

Image-Stream-Nutzer

Der häufigste Consumer von Bildstreams ist SurfaceFlinger, der Systemdienst, der die aktuell sichtbaren Oberflächen nutzt und sie mithilfe von Informationen des Window Managers auf dem Display zusammenstellt. SurfaceFlinger ist der einzige Dienst, der den Inhalt des Displays ändern kann. SurfaceFlinger verwendet OpenGL und den Hardware Composer (HWC), um eine Gruppe von Oberflächen zusammenzustellen.

Andere OpenGL ES-Apps können auch Bildstreams nutzen, z. B. die Kamera-App, die einen Kameravorschaubildstream nutzt. Nicht-GL-Apps können auch Consumer sein, z. B. die ImageReader-Klasse.

Hardware Composer

Die Hardwareabstraktion für das Display-Subsystem. SurfaceFlinger kann bestimmte Kompositionsaufgaben an den HWC delegieren, um OpenGL und die GPU zu entlasten. SurfaceFlinger fungiert als weiterer OpenGL ES-Client. Wenn SurfaceFlinger also aktiv einen oder zwei Puffer in einen dritten zusammenfügt, wird beispielsweise OpenGL ES verwendet. Dadurch ist das Compositing weniger energieintensiv als wenn die GPU alle Berechnungen durchführt.

Das Hardware Composer HAL übernimmt die andere Hälfte der Arbeit und ist der zentrale Punkt für das gesamte Android-Grafikrendering. Das HWC muss Ereignisse unterstützen, darunter VSync (ein weiteres ist Hotplug für Plug-and-Play-HDMI-Unterstützung).

Gralloc

Der Gralloc-Allocator (Graphics Memory Allocator) ist erforderlich, um von Bildproduzenten angeforderten Speicher zuzuweisen. Weitere Informationen finden Sie unter BufferQueue und Gralloc.

Datenfluss

Das folgende Diagramm zeigt die Android-Grafikpipeline:

Grafikdatenfluss

Abbildung 2: Grafische Darstellung des Datenflusses durch Android.

Die Objekte auf der linken Seite sind Renderer, die Grafikpuffer erzeugen, z. B. der Startbildschirm, die Statusleiste und die System-UI. SurfaceFlinger ist der Compositor und HWC ist der Composer.

BufferQueue

BufferQueues stellen die Verbindung zwischen den Android-Grafikkomponenten her. Dies sind zwei Warteschlangen, die den ständigen Zyklus von Puffern vom Ersteller zum Nutzer steuern. Nachdem die Producer ihre Puffer übergeben haben, ist SurfaceFlinger dafür verantwortlich, alles auf dem Display zusammenzufügen.

Das folgende Diagramm veranschaulicht den Kommunikationsprozess von BufferQueue:

BufferQueue-Kommunikationsprozess

Abbildung 3: BufferQueue-Kommunikationsprozess.

BufferQueue enthält die Logik, die Bildstream-Ersteller und Bildstream-Nutzer miteinander verbindet. Beispiele für Bildproduzenten sind die Kameravorschaubilder, die von der Kamera-HAL oder OpenGL ES-Spielen erstellt werden. Beispiele für Bild-Consumer sind SurfaceFlinger oder eine andere App, die einen OpenGL ES-Stream anzeigt, z. B. die Kamera-App, die den Sucher der Kamera anzeigt.

BufferQueue ist eine Datenstruktur, die einen Pufferpool mit einer Warteschlange kombiniert und die Binder-IPC (Inter-Process Communication) verwendet, um Puffer zwischen Prozessen zu übergeben. Die Producer-Schnittstelle oder das, was Sie an jemanden weitergeben, der Grafikpuffer generieren möchte, ist IGraphicBufferProducer (Teil von SurfaceTexture). BufferQueue wird häufig verwendet, um auf einer Surface zu rendern und mit einem GL-Consumer zu verwenden.

BufferQueue kann in drei verschiedenen Modi ausgeführt werden:

synchroner Modus
BufferQueue arbeitet standardmäßig in einem synchronen Modus, in dem jeder vom Producer eingehende Puffer an den Consumer ausgegeben wird. In diesem Modus wird nie ein Puffer verworfen. Wenn der Producer zu schnell ist und Puffer schneller erstellt, als sie geleert werden, wird er blockiert und wartet auf kostenlose Puffer.
nicht blockierender Modus
BufferQueue kann auch in einem nicht blockierenden Modus ausgeführt werden, in dem in diesen Fällen ein Fehler generiert wird, anstatt auf einen Puffer zu warten. In diesem Modus werden auch keine Puffer verworfen. Dies ist nützlich, um potenzielle Deadlocks in Anwendungssoftware zu vermeiden, die die komplexen Abhängigkeiten des Grafik-Frameworks möglicherweise nicht versteht.
Verwerfungsmodus
BufferQueue kann so konfiguriert werden, dass alte Puffer verworfen werden, anstatt Fehler zu generieren oder zu warten. Wenn Sie beispielsweise GL-Rendering für eine Texturansicht durchführen und so schnell wie möglich zeichnen, müssen Puffer gelöscht werden.

Für die meisten dieser Aufgaben fungiert SurfaceFlinger als weiterer OpenGL ES-Client. Wenn SurfaceFlinger also aktiv einen oder zwei Puffer in einen dritten zusammenfügt, wird beispielsweise OpenGL ES verwendet.

Die andere Hälfte der Arbeit wird von der Hardware Composer-HAL erledigt. Dieses HAL ist der zentrale Punkt für das Rendern aller Android-Grafiken.