ViewCapture ist ein Softwaretool, das die Eigenschaften der Ansichten (z. B. Position, Größe, Maßstab und Sichtbarkeit) erfasst, die an die Fenster angehängt sind, an die es angehängt ist. ViewCapture erfasst Informationen zu den verschiedenen Ansichten in einem Fenster und deren Eigenschaften. So können Sie den Status der Nutzererfahrung zu bestimmten Zeitpunkten ermitteln und Änderungen im Zeitverlauf nachvollziehen.
Mit Bildschirmaufzeichnungen lässt sich der Status einer Ansicht zu einem bestimmten Zeitpunkt visualisieren und zeigen, wie er sich ändert. Sie erfordern jedoch erhebliche CPU-Ressourcen und können sich auf die Leistung auswirken. Das ViewCapture-Tool hat weniger Auswirkungen auf die Ressourcen und kann häufiger aktiviert werden. Außerdem werden in ViewCapture Visualisierungen Frame für Frame auf Ansichtsebene angezeigt. So lässt sich der Ansichtsstatus zu bestimmten Zeitpunkten einfacher prüfen als bei Bildschirmaufzeichnungen.
Auf dieser Seite wird beschrieben, wie Sie ViewCapture in System-Apps einbinden.
Verwenden
ViewCapture.java implementiert eine Instanz von onDrawListener und erfasst während des Zeichenvorgangs einen ViewCapture-Trace. Jedes Neuzeichnen eines Frames löst einen Durchlauf der Ansichtsbaumhierarchie aus, der mit der Stammansicht des Fensters beginnt.
ViewCapture verwendet öffentliche View.java-Getter-Methoden, um Werte abzurufen und zur Leistungssteigerung in einen Hintergrundthread zu kopieren. Die ViewCapture-Implementierung optimiert diesen Prozess, indem sie mit captureViewTree prüft, ob eine Ansicht geändert oder ungültig ist. So wird das Durchlaufen der gesamten Ansichtshierarchie vermieden. captureViewTree ist nur für System-Apps verfügbar und Teil der UnsupportedAppUsage API.
Die Nutzung dieser API ist für Apps basierend auf ihrer Ziel-SDK-Version eingeschränkt.
Beschränkungen
In diesem Abschnitt werden die Leistungs- und Speicherbeschränkungen von ViewCapture beschrieben.
Leistung
Der durchschnittliche Mainthread-Overhead für die ViewCapture-Leistung beträgt 195 μs. Im schlimmsten Fall kann es jedoch etwa 5 ms dauern. Weitere Informationen finden Sie im vc#onDraw-Slice im Perfetto-Trace.
Die Gemeinkosten sind hauptsächlich auf die folgenden Aktionen zurückzuführen:
- Das Durchlaufen der Hierarchie kostet 50 μs, auch wenn sie gekürzt wird.
- Das Abrufen von Objekten aus einem Freelist-Allocator zum Speichern von Kopien von Ansichtseigenschaften kostet 20 μs.
- Wenn jeder Property-Wert über eine Getter-Funktion abgerufen wird, sind viele zusätzliche Funktionsaufrufe pro Ansicht erforderlich, was 110 μs kostet.
Daher wirkt sich die Aktivierung von ViewCapture im Always-on-Tracing (AOT) negativ auf die Systemleistung aus und führt zu Rucklern. Aufgrund dieser Leistungs- und Speicherbeschränkungen ist dieser Ansatz nicht für AOT geeignet. Wir empfehlen ViewCapture nur für das Debugging im Lab und lokal.
Arbeitsspeicher
Bei der Methode von Perfetto für ViewCapture-Traces wird ein einzelner Ringpuffer mit einem vordefinierten Speicherbedarf verwendet, um übermäßigen Speicherverbrauch zu verhindern. So wird ein übermäßiger Arbeitsspeicherverbrauch verhindert, da keine separaten Ringpuffer für jedes Fenster erforderlich sind. Das Problem, dass die gesamte Ansichtshierarchie für jeden Status in Perfetto für jeden Frame gespeichert wird, wird dadurch jedoch nicht behoben. Wenn Sie ein einzelnes Fenster wie NexusLauncher aufzeichnen, können in einem 10 MB großen Puffer ViewCapture-Daten für mehr als 30 Sekunden gespeichert werden. Wenn Sie mehr als 30 Fenster aus der System-UI aufnehmen, benötigen Sie entweder einen größeren Puffer oder eine deutlich kürzere Aufnahmezeit.
Anleitung
So richten Sie ViewCapture in System-Apps ein:
- Fügen Sie die Abhängigkeit der Datei - Android.bphinzu, wie im Launcher-Code gezeigt.- android_library { name: "YourLib", static_libs: [ ... "//frameworks/libs/systemui:view_capture", ... ], platform_apis: true, privileged: true, }
- Erstellen Sie beim Erstellen des Fensters eine ViewCapture-Instanz, z. B.: - 
private SafeCloseable mViewCapture; @Override protected void onCreate(Bundle savedInstanceState) { ... mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow()); }
- 
private SafeCloseable mViewCapture; @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (enableViewCaptureTracing()) { mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext()) .startCapture(getRootView(), ".NotificationShadeWindowView"); } ... }
 
- 
- Schließen Sie die ViewCapture-Instanz, wenn Sie das Fenster schließen, wie in den folgenden Beispielen gezeigt: - 
@Override public void onDestroy() { ... if (mViewCapture != null) mViewCapture.close(); }
- 
@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mViewCaptureCloseable != null) { mViewCaptureCloseable.close(); } ... }
 
- 
