Die Verwendung des Mobilfunkmoduls zur Datenübertragung ist potenziell eine der größten Ursachen für die Akkuentladung deiner App. Wenn du die Akkuentladung durch Netzwerkaktivitäten minimieren möchtest, musst du wissen, wie sich dein Verbindungsmodell auf die zugrunde liegende Funkhardware auswirkt.
In diesem Abschnitt wird die Zustandsmaschine für die Mobilfunkverbindung vorgestellt und erläutert, wie das Verbindungsmodell deiner App damit interagiert. Anschließend werden verschiedene Techniken vorgestellt, mit denen sich die Auswirkungen des Datenverbrauchs Ihrer App auf den Akku minimieren lassen.
Zustandsautomat für Radio
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 ist oder sich im Stand-by-Modus befindet, verbraucht es dagegen nur sehr wenig Strom.
Ein wichtiger Faktor ist, dass das Funkmodul nicht sofort vom Stand-by-Modus in den vollständig aktiven Modus wechseln kann. Beim „Einschalten“ des Funkmoduls kommt es zu einer Latenzzeit. Der Akku wechselt also langsam von höheren zu niedrigeren Energiezuständen, um Strom zu sparen, wenn er nicht verwendet wird. Gleichzeitig wird versucht, die Latenz beim „Einschalten“ des Funkmoduls zu minimieren.
Die Zustandsmaschine für ein typisches 3G-Netzwerk 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 Energieverbrauch: Ein Zwischenzustand, der den Akkuverbrauch um etwa 50 % senkt.
- Stand-by: Der Zustand mit dem geringsten Stromverbrauch, in dem keine Netzwerkverbindung aktiv ist.
In den Zuständen „Niedrig“ und „Stand-by“ wird zwar deutlich weniger Akkuleistung verbraucht, aber es kommt auch zu erheblichen Latenzen bei Netzwerkanfragen. Die Rückkehr vom niedrigen Zustand zur vollen Leistung dauert etwa 1, 5 Sekunden.Der Wechsel vom Stand-by-Modus zur vollen Leistung kann mehr als 2 Sekunden dauern.
Um die Latenz zu minimieren, verwendet die Zustandsmaschine eine Verzögerung, um den Übergang zu niedrigeren Energiezuständen zu verschieben. In Abbildung 1 werden die Zeitangaben von AT&T für ein typisches 3G-Funkmodul verwendet.
Abbildung 1: Typische Zustandsmaschine für 3G-Mobilfunk.
Die Funk-Zustandsmaschine auf jedem Gerät, insbesondere die zugehörige Übergangsverzögerung („Tail Time“) und die Startlatenz, variiert je nach verwendeter Funktechnologie (3G, LTE, 5G usw.) und wird vom Mobilfunknetz definiert und konfiguriert, über das das Gerät betrieben wird.
Auf dieser Seite wird eine repräsentative Zustandsmaschine für ein typisches 3G-Mobilfunknetz beschrieben, basierend auf Daten von AT&T. Die allgemeinen Prinzipien und die daraus resultierenden Best Practices gelten jedoch für alle Implementierungen von Mobilfunkmodems.
Dieser Ansatz ist besonders effektiv für das typische Surfen im mobilen Web, da er unerwünschte Latenzen beim Surfen im Web verhindert. Die relativ kurze Nachlaufzeit sorgt auch dafür, dass das Funkmodul nach Beendigung einer Browsersitzung in einen niedrigeren Energiezustand wechseln kann.
Leider kann dieser Ansatz bei modernen Smartphone-Betriebssystemen wie Android zu ineffizienten Apps führen, da 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 die Funk-Zustandsmaschine
Jedes Mal, wenn du eine neue Netzwerkverbindung erstellst, wechselt das Funkmodul in den Zustand mit voller Leistung. Im Fall der zuvor beschriebenen typischen 3G-Funk-Zustandsmaschine bleibt das Gerät während der Übertragung auf voller Leistung, plus weitere 5 Sekunden Nachlaufzeit, gefolgt von 12 Sekunden im Energiesparmodus. Bei einem typischen 3G-Gerät führt jede Datenübertragungssitzung dazu, dass das Funkmodul mindestens 18 Sekunden lang Energie verbraucht.
In der Praxis bedeutet dies, dass eine App, die dreimal pro Minute eine Datenübertragung von einer Sekunde durchführt, die Funkverbindung dauerhaft aktiv hält und sie wieder in den Hochleistungsmodus versetzt, sobald sie in den Stand-by-Modus wechselt.
Abbildung 2: Relative Funksignalleistung für eine einsekündige Übertragung, die dreimal pro Minute ausgeführt wird. Die Abbildung enthält nicht die Latenz zwischen den Ausführungen.
Wenn dieselbe App ihre Datenübertragungen bündelt und jede Minute eine einzelne dreisekündige Übertragung ausführt, bleibt das Funkmodul im Vergleich dazu nur insgesamt 20 Sekunden pro Minute im Hochleistungszustand. So könnte das Funkmodul 40 Sekunden pro Minute im Stand-by-Modus bleiben, was den Akkuverbrauch erheblich senken würde.
Abbildung 3: Relative Funksignalleistung für 3-Sekunden-Übertragungen, die einmal pro Minute ausgeführt werden.
Optimierungstechniken
Nachdem ihr nun wisst, wie sich der Netzwerkzugriff auf die Akkulaufzeit auswirkt, möchten wir euch einige Möglichkeiten vorstellen, wie ihr den Akkuverbrauch reduzieren und gleichzeitig eine schnelle und flüssige Nutzung ermöglichen könnt.
Datenübertragungen bündeln
Wie im vorherigen Abschnitt erwähnt, ist das Bündeln von Datenübertragungen, sodass mehr Daten seltener übertragen werden, eine der besten Möglichkeiten, die Akkueffizienz zu verbessern.
Das ist natürlich nicht immer möglich, wenn deine App als Reaktion auf eine Nutzeraktion sofort Daten empfangen oder senden muss. Sie können dies vermeiden, indem Sie Daten vorab abrufen. Andere Szenarien, z. B. 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. Tipps zum Planen von Hintergrundnetzwerkübertragungen finden Sie unter Von der App initiierte Aufgaben optimieren.
Daten-Prefetch
Das Vorabrufen von Daten ist eine weitere effektive Möglichkeit, die Anzahl der unabhängigen Datenübertragungssitzungen zu reduzieren, die Ihre App ausführt. Beim Prefetching antizipiert die App, wenn der Nutzer eine Aktion in der App ausführt, welche Daten am wahrscheinlichsten für die nächste Reihe von Nutzeraktionen benötigt werden, und ruft diese Daten in einem einzigen Burst über eine einzige Verbindung mit voller Kapazität ab.
Wenn du deine Übertragungen vorab lädst, reduzierst du die Anzahl der Funkaktivierungen, die zum Herunterladen der Daten erforderlich sind. Dadurch wird nicht nur die Akkulaufzeit verlängert, sondern auch die Latenz verbessert, die erforderliche Bandbreite verringert und die Downloadzeiten verkürzt.
Das Prefetching verbessert auch die Nutzerfreundlichkeit, da die Latenz in der App minimiert wird, die durch das Warten auf den Abschluss von Downloads vor dem Ausführen einer Aktion oder dem Ansehen von Daten verursacht wird.
Hier ein Praxisbeispiel:
Ein Nachrichtenleser
Viele Nachrichten-Apps versuchen, die Bandbreite zu reduzieren, indem sie Schlagzeilen erst herunterladen, wenn eine Kategorie ausgewählt wurde, vollständige Artikel nur, wenn der Nutzer sie lesen möchte, und Miniaturansichten nur, wenn sie in den sichtbaren Bereich gescrollt werden.
Bei diesem Ansatz muss das Funkmodul während des Großteils der Nachrichtensitzung der Nutzer aktiv bleiben, während sie durch Schlagzeilen scrollen, Kategorien wechseln und Artikel lesen. Darüber hinaus führt das ständige Wechseln zwischen den Energiezuständen zu erheblichen Latenzen beim Wechseln von Kategorien oder beim Lesen von Artikeln.
Ein besserer Ansatz besteht darin, beim Start eine angemessene Datenmenge vorab abzurufen. Beginne mit dem ersten Satz von Schlagzeilen und Miniaturansichten, um eine geringe Latenz beim Start zu gewährleisten. Fahre dann mit den restlichen Schlagzeilen und Miniaturansichten sowie dem Artikeltext für jeden Artikel fort, der mindestens in der Liste der Hauptschlagzeilen 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 festgelegten Zeitplan. Bei diesem Ansatz besteht die Gefahr, dass viel Bandbreite und Akkulaufzeit 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 zwar viele Vorteile, birgt aber auch das Risiko, dass der Akkuverbrauch und die Bandbreitennutzung sowie das Downloadkontingent steigen, wenn Daten heruntergeladen werden, die nicht verwendet werden. Außerdem ist es wichtig, dass das Prefetching den Start der Anwendung nicht verzögert, während die App auf den Abschluss des Prefetchings wartet. In der Praxis kann das bedeuten, dass Daten schrittweise verarbeitet werden oder dass aufeinanderfolgende Übertragungen so priorisiert werden, dass die für den Start der Anwendung 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 grobe Richtlinie gilt: Basierend auf der zuvor beschriebenen Zustandsmaschine können Sie für Daten, die mit einer Wahrscheinlichkeit von 50% in der aktuellen Nutzersitzung verwendet werden, in der Regel etwa 6 Sekunden (ca. 1–2 Megabyte) vorab abrufen, bevor die potenziellen Kosten für das Herunterladen nicht verwendeter Daten den potenziellen Einsparungen entsprechen, die sich daraus ergeben, dass diese Daten nicht heruntergeladen werden.
Im Allgemeinen empfiehlt es sich, Daten so vorab abzurufen, dass nur alle 2 bis 5 Minuten ein weiterer Download im Bereich von 1 bis 5 Megabyte gestartet werden muss.
Nach diesem Prinzip sollten große Downloads wie Videodateien in regelmäßigen Abständen (alle 2 bis 5 Minuten) in Blöcken heruntergeladen werden. Dabei werden nur die Videodaten vorab abgerufen, die wahrscheinlich in den nächsten Minuten angesehen werden.
Eine Lösung besteht darin, den vollständigen Download nur dann zu planen, wenn eine WLAN-Verbindung besteht und das Gerät möglicherweise gerade geladen wird. Die WorkManager API unterstützt genau diesen Anwendungsfall. Sie können damit die Hintergrundarbeit einschränken, bis das Gerät die vom Entwickler festgelegten Kriterien erfüllt, z. B. dass es aufgeladen wird und mit dem WLAN verbunden ist.
Vor dem Senden von Anfragen die Verbindung prüfen
Die Suche nach einem Mobilfunksignal ist einer der energieintensivsten Vorgänge auf einem Mobilgerät. Eine Best Practice für vom Nutzer initiierte Anfragen besteht darin, zuerst mit ConnectivityManager nach einer Verbindung zu suchen, wie unter Verbindungsstatus und getaktete Verbindung überwachen beschrieben.
Wenn kein Netzwerk verfügbar ist, kann die App den Akku schonen, indem sie die Suche des Mobilfunkmoduls nicht erzwingt. Die Anfrage kann dann geplant und in einem Batch mit anderen Anfragen ausgeführt werden, wenn eine Verbindung hergestellt wird.
Poolverbindungen
Eine weitere Strategie, die zusätzlich zum Batching und Prefetching hilfreich sein kann, ist das Pooling der Netzwerkverbindungen Ihrer App.
Im Allgemeinen ist es effizienter, vorhandene Netzwerkverbindungen wiederzuverwenden, als neue zu initiieren. Durch die Wiederverwendung von Verbindungen kann das Netzwerk auch intelligenter auf Überlastungen und damit verbundene Netzwerkdatenprobleme reagieren.
HttpURLConnection und die meisten HTTP-Clients wie OkHttp aktivieren standardmäßig das Verbindungspooling und verwenden dieselbe Verbindung für mehrere Anfragen wieder.
Zusammenfassung und Ausblick
In diesem Abschnitt hast du viel über die drahtlose Funkverbindung und einige Strategien gelernt, die du allgemein anwenden kannst, 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 genauer an, die bei den meisten Apps üblich sind. Sie lernen die Treiber für jeden dieser Typen sowie moderne Techniken und APIs kennen, um diese Interaktionen effizient zu verwalten.