Netzwerkzugriff optimieren

Die Verwendung des Funkmoduls zum Übertragen von Daten ist möglicherweise eine der größten Ursachen für den Akkuverbrauch Ihrer App. Um den Akkuverbrauch durch Netzwerkaktivitäten zu minimieren, ist es wichtig, dass Sie wissen, wie sich Ihr Verbindungsmodell auf die zugrunde liegende Funkhardware auswirkt.

In diesem Abschnitt wird der Statusautomat für die drahtlose Funkverbindung vorgestellt und es wird erläutert, wie das Verbindungsmodell Ihrer App damit interagiert. Anschließend werden verschiedene Techniken vorgestellt, mit denen sich die Auswirkungen des Datenverbrauchs Ihrer App auf den Akku minimieren lassen.

Die Radio-Zustandsmaschine

Das Funkmodul auf dem Gerät des Nutzers verfügt über integrierte Energiesparfunktionen, die den Akkuverbrauch minimieren. Wenn das Funkmodul vollständig aktiv ist, verbraucht es viel Strom. Wenn es inaktiv oder im Stand-by-Modus ist, verbraucht es nur sehr wenig Strom.

Ein wichtiger Faktor ist, dass das Funkgerät nicht sofort vom Stand-by-Modus in den vollständig aktiven Modus wechseln kann. Das „Hochfahren“ des Funkmoduls ist mit einer Latenzzeit verbunden. Der Akku wechselt also langsam von höheren zu niedrigeren Energiezuständen, um bei Nichtgebrauch Strom zu sparen und gleichzeitig die Latenz beim „Hochfahren“ des Funkmoduls zu minimieren.

Die Zustandsmaschine für ein typisches 3G-Netzwerkfunkgerät besteht aus drei Energiezuständen:

  • Volle Leistung: Wird verwendet, wenn eine Verbindung aktiv ist. Das Gerät kann Daten mit der höchstmöglichen Rate übertragen.
  • Niedriger Stromverbrauch: Ein Zwischenzustand, in dem der Akkuverbrauch um etwa 50 % reduziert wird.
  • Standby: Der Zustand mit dem geringsten Stromverbrauch, in dem keine Netzwerkverbindung aktiv ist.

Im Low- und Standby-Zustand wird zwar deutlich weniger Akku verbraucht, aber es kommt auch zu einer erheblichen Latenz bei Netzwerkanfragen. Es dauert etwa 1,5 Sekunden, bis das Gerät aus dem niedrigen Zustand wieder die volle Leistung erreicht, und über 2 Sekunden, bis es aus dem Stand-by-Modus die volle Leistung erreicht.

Um die Latenz zu minimieren, wird in der Zustandsmaschine eine Verzögerung verwendet, um den Übergang zu niedrigeren Energiezuständen aufzuschieben. In Abbildung 1 werden die Zeitangaben von AT&T für ein typisches 3G-Funkgerät verwendet.


Abbildung 1: Typische 3G-Funkzustandsmaschine.

Der Funkstatusautomat auf jedem Gerät, insbesondere die zugehörige Übergangsverzögerung („Tail Time“) und Startlatenz, variiert je nach verwendeter Funktechnologie (3G, LTE, 5G usw.) und wird vom Mobilfunkanbieter definiert und konfiguriert, über dessen Netzwerk das Gerät betrieben wird.

Auf dieser Seite wird ein repräsentativer Zustandsautomat für ein typisches 3G-Funkgerät beschrieben, basierend auf Daten von AT&T. Die allgemeinen Grundsätze und die daraus resultierenden Best Practices gelten jedoch für alle Implementierungen von Funktechnologien.

Dieser Ansatz ist besonders effektiv für das typische mobile Surfen im Web, da er unerwünschte Latenzzeiten verhindert. Die relativ kurze Tail-Zeit sorgt auch dafür, dass das Funkgerät nach Beendigung einer Browsersitzung in einen Energiesparmodus wechseln kann.

Leider kann dieser Ansatz zu ineffizienten Apps auf modernen Smartphone-Betriebssystemen wie Android führen, bei denen Apps sowohl im Vordergrund (wo die Latenz wichtig ist) als auch im Hintergrund (wo die Akkulaufzeit priorisiert werden sollte) ausgeführt werden.

Auswirkungen von Apps auf den Funkstatusautomaten

Jedes Mal, wenn Sie eine neue Netzwerkverbindung herstellen, wechselt das Funkmodul in den Zustand mit voller Leistung. Im Fall der oben beschriebenen typischen 3G-Funkzustandsmaschine bleibt sie für die Dauer der Übertragung auf voller Leistung – plus weitere 5 Sekunden – und wechselt dann für 12 Sekunden in den Energiesparmodus. Bei einem typischen 3G-Gerät verbraucht das Funkmodul also bei jeder Datenübertragungssitzung mindestens 18 Sekunden lang Energie.

In der Praxis bedeutet das, dass eine App, die dreimal pro Minute eine Sekunde lang Daten überträgt, das Funkmodul ständig aktiv hält und es in den Modus mit hoher Leistung zurückversetzt, sobald es in den Stand-by-Modus wechselt.


Abbildung 2: Relativer Funkstromverbrauch für eine Sekunde Übertragung, die dreimal pro Minute ausgeführt wird. Die Abbildung schließt die Latenz zwischen den Läufen aus, die durch das Hochfahren entsteht.

Wenn dieselbe App ihre Datenübertragungen bündeln würde und jede Minute eine einzelne dreisekündige Übertragung ausführen würde, bliebe das Funkmodul insgesamt nur 20 Sekunden pro Minute im Zustand mit hoher Leistung. Dadurch kann das Funkgerät 40 Sekunden pro Minute im Stand-by-Modus sein, was zu einer erheblichen Reduzierung des Akkuverbrauchs führt.


Abbildung 3: Relativer Funkstromverbrauch für Übertragungen von drei Sekunden, die einmal pro Minute ausgeführt werden.

Optimierungstechniken

Nachdem Sie nun wissen, wie sich der Netzwerkzugriff auf die Akkulaufzeit auswirkt, möchten wir Ihnen einige Möglichkeiten vorstellen, wie Sie den Akkuverbrauch verringern und gleichzeitig eine schnelle und flüssige Nutzererfahrung bieten können.

Datenübertragungen bündeln

Wie im vorherigen Abschnitt beschrieben, ist das Bündeln von Datenübertragungen, sodass Sie weniger oft mehr Daten übertragen, eine der besten Möglichkeiten, die Akkueffizienz zu verbessern.

Das ist natürlich nicht immer möglich, wenn Ihre App Daten sofort als Reaktion auf eine Nutzeraktion empfangen oder senden muss. Sie können dieses Problem beheben, indem Sie Daten vorab abrufen. Weitere Informationen Andere Szenarien wie das Senden von Protokollen oder Analysen an einen Server und andere nicht dringende, von der App initiierte Datenübertragungen eignen sich sehr gut für die Batchverarbeitung und Bündelung. Unter Von der App initiierte Aufgaben optimieren finden Sie Tipps zum Planen von Netzwerkübertragungen im Hintergrund.

Daten vorab abrufen

Das Vorabrufen von Daten ist eine weitere effektive Möglichkeit, die Anzahl der unabhängigen Datenübertragungssitzungen zu reduzieren, die von Ihrer App ausgeführt werden. Beim Prefetching wird, wenn der Nutzer eine Aktion in Ihrer App ausführt, vorhergesehen, welche Daten für die nächste Reihe von Nutzeraktionen am wahrscheinlichsten benötigt werden. Diese Daten werden dann in einem einzigen Burst über eine einzige Verbindung mit voller Kapazität abgerufen.

Wenn Sie die Übertragungen vorab ausführen, reduzieren Sie die Anzahl der Funkaktivierungen, die zum Herunterladen der Daten erforderlich sind. Dadurch wird nicht nur der Akku geschont, sondern auch die Latenz verbessert, die erforderliche Bandbreite verringert und die Downloadzeiten verkürzt.

Durch das Prefetching wird auch die Nutzerfreundlichkeit verbessert, da die Latenz in der App minimiert wird, die durch das Warten auf den Abschluss von Downloads entsteht, bevor eine Aktion ausgeführt oder Daten angezeigt werden können.

Hier ein praktisches Beispiel.

Ein Newsreader

Viele Nachrichten-Apps versuchen, die Bandbreite zu reduzieren, indem sie Überschriften erst herunterladen, nachdem eine Kategorie ausgewählt wurde, vollständige Artikel nur, wenn der Nutzer sie lesen möchte, und Thumbnails erst, wenn sie in den sichtbaren Bereich gescrollt werden.

Bei dieser Methode bleibt das Funkmodul für die meisten Nutzer während ihrer gesamten News-Lesesitzung aktiv, da sie durch Schlagzeilen scrollen, Kategorien wechseln und Artikel lesen. Außerdem führt das ständige Umschalten zwischen Energiezuständen zu einer erheblichen Latenz beim Wechseln von Kategorien oder beim Lesen von Artikeln.

Ein besserer Ansatz besteht darin, beim Start eine angemessene Menge an Daten vorab abzurufen. Beginnen Sie mit den ersten Nachrichtenüberschriften und ‑thumbnails, um eine niedrige Latenz beim Start zu gewährleisten. Fahren Sie dann mit den verbleibenden Überschriften und Thumbnails sowie dem Artikeltext für jeden Artikel fort, der mindestens in der primären Überschriftenliste verfügbar ist.

Eine weitere Alternative besteht darin, alle Überschriften, Thumbnails, Artikeltexte und möglicherweise sogar vollständige Artikelbilder vorab abzurufen – in der Regel im Hintergrund nach einem vorgegebenen Zeitplan. Bei diesem Ansatz besteht das Risiko, dass viel Bandbreite und Akku für das Herunterladen von Inhalten verbraucht werden, die nie verwendet werden. Er sollte daher mit Vorsicht implementiert werden.

Weitere Überlegungen

Das Vorabrufen von Daten bietet viele Vorteile, birgt aber auch das Risiko, dass der Akku schneller entladen wird und mehr Bandbreite und Downloadkontingent verbraucht werden, da Daten heruntergeladen werden, die nicht verwendet werden. Außerdem ist es wichtig, dass das Vorabrufen den Start der Anwendung nicht verzögert, während die App darauf wartet, dass das Vorabrufen abgeschlossen wird. In der Praxis kann das bedeuten, dass Daten progressiv verarbeitet werden oder dass aufeinanderfolgende Übertragungen so priorisiert werden, dass die für den Anwendungsstart erforderlichen Daten zuerst heruntergeladen und verarbeitet werden.

Wie aggressiv Sie Daten vorab abrufen, hängt von der Größe der heruntergeladenen Daten und der Wahrscheinlichkeit ab, dass sie verwendet werden. Als Faustregel gilt, dass Sie anhand des oben beschriebenen Zustandsautomaten bei Daten, die mit einer Wahrscheinlichkeit von 50% in der aktuellen Nutzersitzung verwendet werden, in der Regel etwa 6 Sekunden lang (ca. 1–2 MB) vorab abrufen können, bevor die potenziellen Kosten für das Herunterladen ungenutzter Daten den potenziellen Einsparungen entsprechen, die sich ergeben, wenn diese Daten gar nicht erst heruntergeladen werden.

Im Allgemeinen ist es empfehlenswert, Daten so vorab abzurufen, dass Sie nur alle 2 bis 5 Minuten einen weiteren Download starten müssen, und zwar in der Größenordnung von 1 bis 5 MB.

Gemäß diesem Prinzip sollten große Downloads wie Videodateien in regelmäßigen Abständen (alle 2 bis 5 Minuten) in Blöcken heruntergeladen werden. So werden nur die Videodaten vorab abgerufen, die wahrscheinlich in den nächsten Minuten angesehen werden.

Eine Lösung besteht darin, den vollständigen Download so zu planen, dass er nur erfolgt, wenn eine WLAN-Verbindung besteht und das Gerät möglicherweise auch nur dann, wenn es geladen wird. Die WorkManager API unterstützt genau diesen Anwendungsfall. Sie können damit Hintergrundaufgaben aufschieben, bis das Gerät die vom Entwickler angegebenen Kriterien erfüllt, z. B. wenn es geladen wird und mit einem WLAN verbunden ist.

Verbindung prüfen, bevor Anfragen gesendet werden

Die Suche nach einem Mobilfunksignal ist einer der energieaufwendigsten Vorgänge auf einem Mobilgerät. Bei nutzerinitiierten Anfragen empfiehlt es sich, zuerst mit ConnectivityManager nach einer Verbindung zu suchen, wie unter Verbindungsstatus und Verbindungsnutzung überwachen beschrieben. Wenn kein Netzwerk vorhanden ist, kann die App Akku sparen, indem sie das Mobilfunkmodul nicht zum Suchen zwingt. Die Anfrage kann dann geplant und in einem Batch mit anderen Anfragen ausgeführt werden, wenn eine Verbindung hergestellt wird.

Poolverbindungen

Eine zusätzliche Strategie, die neben Batching und Prefetching helfen kann, ist das Pooling der Netzwerkverbindungen Ihrer App.

Es ist in der Regel effizienter, vorhandene Netzwerkverbindungen wiederzuverwenden, als neue zu initiieren. Durch die Wiederverwendung von Verbindungen kann das Netzwerk auch intelligenter auf Überlastung und damit zusammenhängende Probleme mit Netzwerkdaten reagieren.

HttpURLConnection und die meisten HTTP-Clients wie OkHttp aktivieren standardmäßig das Verbindungspooling und verwenden dieselbe Verbindung für mehrere Anfragen.

Zusammenfassung und Ausblick

In diesem Abschnitt haben Sie viel über das Funkmodul und einige Strategien gelernt, die Sie allgemein anwenden können, um eine schnelle, reaktionsschnelle Nutzererfahrung zu bieten und gleichzeitig den Akkuverbrauch zu reduzieren.

Im nächsten Abschnitt sehen wir uns drei verschiedene Arten von Netzwerkinteraktionen an, die für die meisten Apps typisch sind. Sie erfahren, welche Faktoren für die einzelnen Typen verantwortlich sind, und lernen moderne Techniken und APIs kennen, mit denen sich diese Interaktionen effizient verwalten lassen.