Anfragen, die deine App an das Netzwerk sendet, sind eine Hauptursache für eine schnelle Akkuentladung da sie energieverbrauchende Mobilfunk- oder WLAN-Funkschnittstellen aktivieren. Jenseits der Macht zum Senden und Empfangen von Paketen benötigt, verbrauchen diese Funkschnittstellen zusätzliche Energie, wird eingeschaltet und bleibt aktiv. Etwas so Einfaches wie eine Netzwerkanfrage alle 15 Sekunden können dafür sorgen, dass das Mobilfunknetz ständig eingeschaltet bleibt und der Akku schnell belastet wird. Energie.
Es gibt drei Arten regelmäßiger Updates:
- Vom Nutzer initiiert. Eine Aktualisierung basierend auf einem bestimmten Nutzerverhalten durchführen, z. B. zum Aktualisieren nach oben ziehen.
- Von der App initiiert: Sie führen regelmäßig eine Aktualisierung durch.
- Vom Server initiiert. Die Durchführung einer Aktualisierung als Reaktion auf eine Benachrichtigung von Server.
In diesem Thema werden diese Punkte näher betrachtet und weitere Möglichkeiten erörtert, optimiert, um den Akku zu schonen.
Vom Nutzer initiierte Anfragen optimieren
Von Nutzern initiierte Anfragen werden normalerweise als Reaktion auf ein bestimmtes Nutzerverhalten ausgeführt. Für Beispiel: Eine App zum Lesen der neuesten Nachrichtenartikel kann dem Nutzer die Möglichkeit bieten, Zum Aktualisieren nach oben ziehen, um nach neuen Artikeln zu suchen. Sie können die wie Sie auf von Nutzern initiierte Anfragen reagieren, Netzwerknutzung.
Nutzeranfragen drosseln
Sie können einige von Nutzern initiierte Anfragen ignorieren, wenn wie mehrfache Gesten zum Aktualisieren über einen kurzen Zeitraum, nach neuen Daten suchen, solange die aktuellen Daten noch aktuell sind. Auf sie reagieren -Anforderung könnte eine erhebliche Menge an Strom verschwenden, da das Radio aktiv bleibt. A effizienteren Ansatz besteht darin, die vom Nutzer initiierten Anfragen zu drosseln, pro Zeitraum nur eine Anfrage gestellt werden kann, wodurch sich die Häufigkeit verwendet wird.
Cache verwenden
Durch das Speichern Ihrer App-Daten im Cache erstellen Sie eine lokale Kopie der Informationen. auf die Ihre App verweisen muss. Ihre App kann dann auf dieselben lokalen mehrfach kopieren, ohne ein Netzwerk öffnen zu müssen um neue Anfragen zu stellen.
Sie sollten Daten so offen wie möglich im Cache speichern, einschließlich statischer Daten. und On-Demand-Downloads wie Bilder in Originalgröße. Sie können HTTP um sicherzustellen, dass Ihre Caching-Strategie nicht zu um veraltete Daten anzuzeigen. Weitere Informationen zum Caching von Netzwerkantworten finden Sie unter Redundante Downloads.
Unter Android 11 und höher kann Ihre App dieselben großen Datasets wie andere Anwendungen für Anwendungsfälle wie maschinelles Lernen und Medienwiedergabe Wenn Ihre App auf ein freigegebenes Dataset zugreifen muss, kann sie zuerst nach einer im Cache gespeicherten Version suchen bevor Sie versuchen, eine neue Kopie herunterzuladen. Weitere Informationen zu freigegebenen Datasets Siehe Auf freigegebene Datasets zugreifen.
Größere Bandbreite verwenden, um mehr Daten seltener herunterzuladen
Bei einer Verbindung über ein drahtloses Funknetz erhöht sich in der Regel eine höhere Bandbreite höhere Akkukosten, was bedeutet, dass 5G normalerweise mehr Energie verbraucht als LTE, das wiederum teurer ist als 3G.
Das bedeutet, dass der zugrunde liegende Funkstatus zwar je nach Funktechnologie, im Allgemeinen die relativen Auswirkungen des Zustands auf die Batterie bei Funkverbindungen mit höherer Bandbreite größer ist. Weitere Informationen zu finden Sie unter Radio State Rechner.
Gleichzeitig bedeutet die höhere Bandbreite, dass Sie mehr aggressiv vorgehen und mehr Daten gleichzeitig herunterladen. Vielleicht weniger weil die Kosten für die Extremwert-Akkulaufzeit relativ höher sind, effizienter, um das Funkgerät bei jeder Übertragung länger aktiv zu halten um die Aktualisierungshäufigkeit zu verringern.
Beispiel: Ein LTE-Funkgerät hat die doppelte Bandbreite und die doppelten Energiekosten. von 3G sollten Sie pro Sitzung viermal so viele Daten herunterladen – oder bis zu 10 MB. Wenn Sie so viele Daten herunterladen, wie sich Ihr Prefetch auf den verfügbaren lokalen Speicher auswirkt, Ihren Prefetch-Cache regelmäßig.
Sie können die
ConnectivityManager
zum Registrieren
einen Listener für das Standardnetzwerk
Zum Registrieren TelephonyManager
ein PhoneStateListener
für
den aktuellen Verbindungstyp des Geräts ermitteln. Sobald der Verbindungstyp bekannt ist,
können Sie Ihre Vorabrufroutinen entsprechend anpassen:
Kotlin
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val tm = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager private var hasWifi = false private var hasCellular = false private var cellModifier: Float = 1f private val networkCallback = object : ConnectivityManager.NetworkCallback() { // Network capabilities have changed for the network override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) hasCellular = networkCapabilities .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) hasWifi = networkCapabilities .hasTransport(NetworkCapabilities.TRANSPORT_WIFI) } } private val phoneStateListener = object : PhoneStateListener() { override fun onPreciseDataConnectionStateChanged( dataConnectionState: PreciseDataConnectionState ) { cellModifier = when (dataConnectionState.networkType) { TelephonyManager.NETWORK_TYPE_LTE or TelephonyManager.NETWORK_TYPE_HSPAP -> 4f TelephonyManager.NETWORK_TYPE_EDGE or TelephonyManager.NETWORK_TYPE_GPRS -> 1/2f else -> 1f } } private class NetworkState { private var defaultNetwork: Network? = null private var defaultCapabilities: NetworkCapabilities? = null fun setDefaultNetwork(network: Network?, caps: NetworkCapabilities?) = synchronized(this) { defaultNetwork = network defaultCapabilities = caps } val isDefaultNetworkWifi get() = synchronized(this) { defaultCapabilities?.hasTransport(TRANSPORT_WIFI) ?: false } val isDefaultNetworkCellular get() = synchronized(this) { defaultCapabilities?.hasTransport(TRANSPORT_CELLULAR) ?: false } val isDefaultNetworkUnmetered get() = synchronized(this) { defaultCapabilities?.hasCapability(NET_CAPABILITY_NOT_METERED) ?: false } var cellNetworkType: Int = TelephonyManager.NETWORK_TYPE_UNKNOWN get() = synchronized(this) { field } set(t) = synchronized(this) { field = t } private val cellModifier: Float get() = synchronized(this) { when (cellNetworkType) { TelephonyManager.NETWORK_TYPE_LTE or TelephonyManager.NETWORK_TYPE_HSPAP -> 4f TelephonyManager.NETWORK_TYPE_EDGE or TelephonyManager.NETWORK_TYPE_GPRS -> 1 / 2f else -> 1f } } val prefetchCacheSize: Int get() = when { isDefaultNetworkWifi -> MAX_PREFETCH_CACHE isDefaultNetworkCellular -> (DEFAULT_PREFETCH_CACHE * cellModifier).toInt() else -> DEFAULT_PREFETCH_CACHE } } private val networkState = NetworkState() private val networkCallback = object : ConnectivityManager.NetworkCallback() { // Network capabilities have changed for the network override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { networkState.setDefaultNetwork(network, networkCapabilities) } override fun onLost(network: Network?) { networkState.setDefaultNetwork(null, null) } } private val telephonyCallback = object : TelephonyCallback(), TelephonyCallback.PreciseDataConnectionStateListener { override fun onPreciseDataConnectionStateChanged(dataConnectionState: PreciseDataConnectionState) { networkState.cellNetworkType = dataConnectionState.networkType } } connectivityManager.registerDefaultNetworkCallback(networkCallback) telephonyManager.registerTelephonyCallback(telephonyCallback) private val prefetchCacheSize: Int get() { return when { hasWifi -> MAX_PREFETCH_CACHE hasCellular -> (DEFAULT_PREFETCH_CACHE * cellModifier).toInt() else -> DEFAULT_PREFETCH_CACHE } } }
Java
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); private boolean hasWifi = false; private boolean hasCellular = false; private float cellModifier = 1f; private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onCapabilitiesChanged( @NonNull Network network, @NonNull NetworkCapabilities networkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities); hasCellular = networkCapabilities .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); hasWifi = networkCapabilities .hasTransport(NetworkCapabilities.TRANSPORT_WIFI); } }; private PhoneStateListener phoneStateListener = new PhoneStateListener() { @Override public void onPreciseDataConnectionStateChanged( @NonNull PreciseDataConnectionState dataConnectionState ) { switch (dataConnectionState.getNetworkType()) { case (TelephonyManager.NETWORK_TYPE_LTE | TelephonyManager.NETWORK_TYPE_HSPAP): cellModifier = 4; Break; case (TelephonyManager.NETWORK_TYPE_EDGE | TelephonyManager.NETWORK_TYPE_GPRS): cellModifier = 1/2.0f; Break; default: cellModifier = 1; Break; } } }; cm.registerDefaultNetworkCallback(networkCallback); tm.listen( phoneStateListener, PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE ); public int getPrefetchCacheSize() { if (hasWifi) { return MAX_PREFETCH_SIZE; } if (hasCellular) { return (int) (DEFAULT_PREFETCH_SIZE * cellModifier); } return DEFAULT_PREFETCH_SIZE; }
Von der App initiierte Anfragen optimieren
Von Apps initiierte Anfragen erfolgen normalerweise nach einem Zeitplan, z. B. über eine App, die Logs oder Analysen an einen Back-End-Dienst senden. Beim Umgang mit App-initiierten die Priorität dieser Anfragen zu prüfen und herauszufinden, ob sie in Batches zusammengefasst werden können. und ob sie erst dann aufgeschoben werden können, wenn das Gerät aufgeladen wird oder die mit einem kostenlosen Netzwerk verbunden ist. Diese Anfragen können mit Bedacht optimiert werden. Planung und die Verwendung von Bibliotheken wie WorkManager
Batch-Netzwerkanfragen
Auf einem Mobilgerät ist der Vorgang das Einschalten des Radios, das Herstellen einer Verbindung und das Radio aktiv zu halten, verbraucht viel Energie. Aus diesem Grund Die Verarbeitung einzelner Anfragen zu zufälligen Zeiten kann viel Strom verbrauchen. und verkürzt die Akkulaufzeit. Ein effizienterer Ansatz besteht darin, eine Reihe von und gemeinsam verarbeiten. So kann das System den Strom Radio nur einmal einschalten, um trotzdem alle Daten zu erhalten, die von eine App.
WorkManager verwenden
Mithilfe der WorkManager
-Bibliothek können Sie Aufgaben nach einem effizienten Zeitplan erledigen.
der berücksichtigt, ob bestimmte Bedingungen erfüllt sind, z. B. die Netzwerkverfügbarkeit
und den Ein/Aus-Status. Angenommen, Sie haben eine
Abgeleitete Worker
-Klasse mit dem Namen
DownloadHeadlinesWorker
, die die neuesten Schlagzeilen abruft. Dieser Worker
kann so geplant werden, dass sie stündlich ausgeführt werden. Voraussetzung ist, dass das Gerät mit einem
nicht getaktetes Netzwerk und Batteriestand des Geräts nicht niedrig, mit benutzerdefinierter Wiederholungsstrategie
, wenn es Probleme beim Abrufen der Daten gibt:
Kotlin
val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresBatteryNotLow(true) .build() val request = PeriodicWorkRequestBuilder<DownloadHeadlinesWorker>(1, TimeUnit.HOURS) .setConstraints(constraints) .setBackoffCriteria(BackoffPolicy.LINEAR, 1L, TimeUnit.MINUTES) .build() WorkManager.getInstance(context).enqueue(request)
Java
Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresBatteryNotLow(true) .build(); WorkRequest request = new PeriodicWorkRequest.Builder(DownloadHeadlinesWorker.class, 1, TimeUnit.HOURS) .setBackoffCriteria(BackoffPolicy.LINEAR, 1L, TimeUnit.MINUTES) .build(); WorkManager.getInstance(this).enqueue(request);
Neben WorkManager bietet die Android-Plattform einige andere Tools damit Sie einen effizienten Zeitplan für die Erledigung von Netzwerkaufgaben erstellen können, z. B. wie Polling. Weitere Informationen zur Verwendung dieser Tools finden Sie in der Leitfaden zur Hintergrundverarbeitung
Vom Server initiierte Anfragen optimieren
Vom Server initiierte Anfragen werden in der Regel als Reaktion auf eine Benachrichtigung von einem Server. Beispiel: Eine App, die die neuesten Nachrichtenartikel liest, eine Benachrichtigung über eine Reihe neuer Artikel erhalten, die es dann herunterlädt.
Serverupdates mit Firebase Cloud Messaging senden
Firebase Cloud Messaging (FCM) ist eine einfache Mechanismus zum Übertragen von Daten von einem Server an eine bestimmte Anwendungsinstanz. Mit FCM kann Ihr Server Ihre auf einem bestimmten Gerät ausgeführte App benachrichtigen, wenn neue Daten verfügbar sind.
Im Vergleich zu Polling, bei dem Ihre Anwendung regelmäßig den Server anpingen muss, um neue Daten haben, ermöglicht dieses ereignisgesteuerte Modell Ihrer App, eine neue Verbindung wenn es weiß, dass Daten heruntergeladen werden können. Das Modell minimiert unnötige und verringert die Latenz beim Aktualisieren von Informationen in Ihrer Anwendung.
FCM wird über eine dauerhafte TCP/IP-Verbindung implementiert. Dadurch wird die Anzahl der Anzahl persistenter Verbindungen und ermöglicht es der Plattform, die Bandbreite und minimieren die entsprechenden Auswirkungen auf die Akkulaufzeit.